@openfort/react 0.1.13 → 0.2.0

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.
Files changed (41) hide show
  1. package/build/assets/icons.d.ts +3 -0
  2. package/build/components/Common/Button/types.d.ts +1 -0
  3. package/build/components/Common/Modal/styles.d.ts +1 -0
  4. package/build/components/Common/OTPInput/index.d.ts +8 -0
  5. package/build/components/Common/OTPInput/styles.d.ts +18 -0
  6. package/build/components/Common/Providers/ProviderHeader.d.ts +7 -0
  7. package/build/components/Common/Providers/ProviderIcon.d.ts +4 -0
  8. package/build/components/Common/Providers/getProviderName.d.ts +2 -0
  9. package/build/components/FloatingGraphic/index.d.ts +3 -1
  10. package/build/components/FloatingGraphic/styles.d.ts +2 -0
  11. package/build/components/Openfort/context.d.ts +2 -0
  12. package/build/components/Openfort/types.d.ts +86 -1
  13. package/build/components/Pages/EmailOTP/index.d.ts +3 -0
  14. package/build/components/Pages/EmailOTP/styles.d.ts +4 -0
  15. package/build/components/Pages/LinkedProvider/index.d.ts +2 -0
  16. package/build/components/Pages/LinkedProviders/styles.d.ts +2 -1
  17. package/build/components/Pages/PhoneOTP/index.d.ts +3 -0
  18. package/build/components/Pages/PhoneOTP/styles.d.ts +4 -0
  19. package/build/components/Pages/Providers/index.d.ts +2 -1
  20. package/build/components/Pages/RemoveLinkedProvider/index.d.ts +2 -0
  21. package/build/hooks/openfort/auth/status.d.ts +3 -1
  22. package/build/hooks/openfort/auth/useAuthCallback.d.ts +7 -10
  23. package/build/hooks/openfort/auth/useEmailAuth.d.ts +2 -3
  24. package/build/hooks/openfort/auth/useEmailOtpAuth.d.ts +29 -0
  25. package/build/hooks/openfort/auth/useGuestAuth.d.ts +2 -2
  26. package/build/hooks/openfort/auth/useOAuth.d.ts +5 -6
  27. package/build/hooks/openfort/auth/usePhoneOtpAuth.d.ts +30 -0
  28. package/build/hooks/openfort/useConnectWithSiwe.d.ts +4 -3
  29. package/build/hooks/openfort/useUser.d.ts +3 -2
  30. package/build/hooks/useConnectCallback.d.ts +3 -3
  31. package/build/hooks/useRouteProps.d.ts +10 -0
  32. package/build/index.d.ts +5 -3
  33. package/build/index.es.js +1715 -548
  34. package/build/index.es.js.map +1 -1
  35. package/build/openfort/CoreOpenfortProvider.d.ts +5 -3
  36. package/build/openfortCustomTypes.d.ts +10 -0
  37. package/build/siwe/create-siwe-message.d.ts +1 -1
  38. package/build/types.d.ts +4 -4
  39. package/build/utils/validation.d.ts +1 -0
  40. package/build/version.d.ts +1 -1
  41. package/package.json +4 -3
package/build/index.es.js CHANGED
@@ -1,16 +1,16 @@
1
- import { Openfort as Openfort$1, EmbeddedState, AccountTypeEnum, SDKConfiguration, RecoveryMethod, MissingRecoveryPasswordError, ChainTypeEnum, OAuthProvider, OpenfortError as OpenfortError$1, OpenfortErrorType as OpenfortErrorType$1 } from '@openfort/openfort-js';
1
+ import { Openfort as Openfort$1, EmbeddedState, AccountTypeEnum, SDKConfiguration, RecoveryMethod, MissingRecoveryPasswordError, ChainTypeEnum, OAuthProvider, OpenfortError as OpenfortError$1 } from '@openfort/openfort-js';
2
2
  export { AccountTypeEnum, OAuthProvider, OpenfortEvents, RecoveryMethod, ThirdPartyOAuthProvider, openfortEvents } from '@openfort/openfort-js';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import React, { useState, useEffect, createContext, useRef, useId, useMemo, useCallback, createElement, useLayoutEffect } from 'react';
5
5
  import { normalize } from 'viem/ens';
6
- import { useEnsAddress, useEnsName, useEnsAvatar, useConfig, useAccount, useBlockNumber, useBalance, useConnectors as useConnectors$1, useConnect as useConnect$1, useDisconnect, useChainId, http, useSwitchChain, useWalletClient, useEstimateGas, useEstimateFeesPerGas, useReadContract, useSendTransaction, useWriteContract, useWaitForTransactionReceipt, usePublicClient, WagmiContext } from 'wagmi';
6
+ import { useEnsAddress, useEnsName, useEnsAvatar, useConfig, useAccount, useBlockNumber, useBalance, useConnectors as useConnectors$1, useConnect as useConnect$1, useDisconnect, useChainId, http, useSwitchChain, useWalletClient, useEstimateGas, useEstimateFeesPerGas, useReadContract, useSendTransaction, useWriteContract, useWaitForTransactionReceipt, usePublicClient, useSignMessage, WagmiContext } from 'wagmi';
7
7
  import { motion, AnimatePresence, MotionConfig } from 'framer-motion';
8
8
  import styled$1, { css, keyframes } from 'styled-components';
9
9
  import { detect } from 'detect-browser';
10
10
  import { useQueryClient, useQuery } from '@tanstack/react-query';
11
11
  import useMeasure from 'react-use-measure';
12
12
  import { Buffer } from 'buffer';
13
- import { mainnet, polygon, optimism, arbitrum, sepolia } from 'wagmi/chains';
13
+ import { mainnet, polygon, optimism, arbitrum } from 'wagmi/chains';
14
14
  import { safe, injected, coinbaseWallet, walletConnect } from '@wagmi/connectors';
15
15
  import { useTransition } from 'react-transition-state';
16
16
  import ResizeObserver from 'resize-observer-polyfill';
@@ -19,7 +19,9 @@ import { numberToHex, formatUnits, parseUnits, isAddress, parseAbi, encodeFuncti
19
19
  import { erc7811Actions, erc7715Actions } from 'viem/experimental';
20
20
  import calculateEntropy from 'fast-password-entropy';
21
21
  import QRCodeUtil from 'qrcode';
22
- import { switchChain, signMessage } from '@wagmi/core';
22
+ import { PhoneInput } from 'react-international-phone';
23
+ import 'react-international-phone/style.css';
24
+ import { switchChain } from '@wagmi/core';
23
25
  import { AxiosError } from 'axios';
24
26
  import { createSiweMessage } from 'viem/siwe';
25
27
  import { hashAuthorization } from 'viem/utils';
@@ -1912,6 +1914,8 @@ const routes = {
1912
1914
  CONNECTED_SUCCESS: 'connectedSuccess',
1913
1915
  CREATE_GUEST_USER: 'createGuestUser',
1914
1916
  EMAIL_LOGIN: 'emailLogin',
1917
+ EMAIL_OTP: 'emailOtp',
1918
+ PHONE_OTP: 'phoneOtp',
1915
1919
  FORGOT_PASSWORD: 'forgotPassword',
1916
1920
  EMAIL_VERIFICATION: 'emailVerification',
1917
1921
  LINK_EMAIL: 'linkEmail',
@@ -1925,7 +1929,9 @@ const routes = {
1925
1929
  CONNECTED: 'connected',
1926
1930
  PROFILE: 'profile',
1927
1931
  SWITCHNETWORKS: 'switchNetworks',
1932
+ LINKED_PROVIDER: 'linkedProvider',
1928
1933
  LINKED_PROVIDERS: 'linkedProviders',
1934
+ REMOVE_LINKED_PROVIDER: 'removeLinkedProvider',
1929
1935
  EXPORT_KEY: 'exportKey',
1930
1936
  NO_ASSETS_AVAILABLE: 'noAssetsAvailable',
1931
1937
  ASSET_INVENTORY: 'assetInventory',
@@ -1952,6 +1958,7 @@ var UIAuthProvider;
1952
1958
  (function (UIAuthProvider) {
1953
1959
  UIAuthProvider["GOOGLE"] = "google";
1954
1960
  UIAuthProvider["TWITTER"] = "twitter";
1961
+ UIAuthProvider["X"] = "twitter";
1955
1962
  UIAuthProvider["FACEBOOK"] = "facebook";
1956
1963
  UIAuthProvider["DISCORD"] = "discord";
1957
1964
  // EPIC_GAMES = "epic_games",
@@ -1959,7 +1966,13 @@ var UIAuthProvider;
1959
1966
  // TELEGRAM = "telegram", // Telegram is not working yet
1960
1967
  UIAuthProvider["APPLE"] = "apple";
1961
1968
  // Extended Providers
1962
- UIAuthProvider["EMAIL"] = "email";
1969
+ /**
1970
+ * @deprecated Use `UIAuthProvider.EMAIL_PASSWORD` or `UIAuthProvider.EMAIL_OTP` instead.
1971
+ */
1972
+ UIAuthProvider["EMAIL"] = "emailPassword";
1973
+ UIAuthProvider["EMAIL_PASSWORD"] = "emailPassword";
1974
+ UIAuthProvider["EMAIL_OTP"] = "emailOtp";
1975
+ UIAuthProvider["PHONE"] = "phone";
1963
1976
  UIAuthProvider["WALLET"] = "wallet";
1964
1977
  UIAuthProvider["GUEST"] = "guest";
1965
1978
  })(UIAuthProvider || (UIAuthProvider = {}));
@@ -4544,6 +4557,7 @@ const CoreOpenfortProvider = ({ children, onConnect, onDisconnect, openfortConfi
4544
4557
  const { connectors, connect, reset } = useConnect();
4545
4558
  const { address } = useAccount();
4546
4559
  const [user, setUser] = useState(null);
4560
+ const [linkedAccounts, setLinkedAccounts] = useState([]);
4547
4561
  const [walletStatus, setWalletStatus] = useState({ status: 'idle' });
4548
4562
  const { disconnectAsync } = useDisconnect();
4549
4563
  const { walletConfig } = useOpenfort();
@@ -4619,7 +4633,9 @@ const CoreOpenfortProvider = ({ children, onConnect, onDisconnect, openfortConfi
4619
4633
  }
4620
4634
  try {
4621
4635
  const user = await openfort.user.get();
4636
+ const linkedAccounts = await openfort.user.list();
4622
4637
  logger.log('Getting user');
4638
+ setLinkedAccounts(linkedAccounts);
4623
4639
  setUser(user);
4624
4640
  return user;
4625
4641
  }
@@ -4803,6 +4819,7 @@ const CoreOpenfortProvider = ({ children, onConnect, onDisconnect, openfortConfi
4803
4819
  isLoading: isLoading(),
4804
4820
  needsRecovery,
4805
4821
  user,
4822
+ linkedAccounts,
4806
4823
  updateUser,
4807
4824
  updateEmbeddedAccounts: fetchEmbeddedAccounts,
4808
4825
  embeddedAccounts,
@@ -4878,7 +4895,7 @@ const SendIcon = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width:
4878
4895
  const ReceiveIcon = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("path", { d: "M19 5L5 19", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: "M15 19H5V9", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" })] }));
4879
4896
  const BuyIcon = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("rect", { x: "3", y: "6", width: "18", height: "12", rx: "2", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: "M3 10H21", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: "M7 14H9", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" })] }));
4880
4897
  const DollarIcon = (props) => (jsxs("svg", { width: "800px", height: "800px", viewBox: "0 0 24 24", role: "img", xmlns: "http://www.w3.org/2000/svg", "aria-labelledby": "dolarIconTitle", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", fill: "none", color: "currentColor", ...props, children: [jsx("title", { id: "dolarIconTitle", children: "Dolar" }), jsx("path", { d: "M12 4L12 6M12 18L12 20M15.5 8C15.1666667 6.66666667 14 6 12 6 9 6 8.5 7.95652174 8.5 9 8.5 13.140327 15.5 10.9649412 15.5 15 15.5 16.0434783 15 18 12 18 10 18 8.83333333 17.3333333 8.5 16" })] }));
4881
- const WalletIcon$2 = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("rect", { x: "3", y: "6", width: "18", height: "14", rx: "2.5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: "M21 10H17C15.8954 10 15 10.8954 15 12C15 13.1046 15.8954 14 17 14H21V10Z", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("circle", { cx: "17", cy: "12", r: "1", fill: "currentColor" })] }));
4898
+ const WalletIcon$1 = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("rect", { x: "3", y: "6", width: "18", height: "14", rx: "2.5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: "M21 10H17C15.8954 10 15 10.8954 15 12C15 13.1046 15.8954 14 17 14H21V10Z", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("circle", { cx: "17", cy: "12", r: "1", fill: "currentColor" })] }));
4882
4899
  const ExternalLinkIcon = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", style: {
4883
4900
  left: 0,
4884
4901
  top: 0,
@@ -4933,6 +4950,7 @@ const RetryIconCircle = ({ ...props }) => {
4933
4950
  };
4934
4951
  const CopyToClipboardIcon = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("path", { d: "M14 9.5V7C14 5.89543 13.1046 5 12 5H7C5.89543 5 5 5.89543 5 7V12C5 13.1046 5.89543 14 7 14H9.5", stroke: "var(--ck-body-color-muted)", strokeWidth: "2" }), jsx("rect", { x: "10", y: "10", width: "9", height: "9", rx: "2", stroke: "var(--ck-body-color-muted)", strokeWidth: "2" }), jsx("path", { d: "M1 3L3 5L7 1", stroke: "var(--ck-body-color)", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" })] }));
4935
4952
  const EmailIcon = ({ ...props }) => (jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 256 256", width: "256", height: "256", children: [jsx("rect", { width: "256", height: "256", fill: "none" }), jsx("path", { d: "M32,96V200a8,8,0,0,0,8,8H216a8,8,0,0,0,8-8V96L128,32Z", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "16" }), jsx("polyline", { points: "224 96 145.46 152 110.55 152 32 96", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "16" })] }));
4953
+ const PhoneIcon = ({ ...props }) => (jsx("svg", { id: "Layer_1", xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink", viewBox: "0 0 32 32", enableBackground: "new 0 0 32 32", xmlSpace: "preserve", ...props, children: jsx("path", { fill: "none", stroke: "currentColor", strokeWidth: 2, strokeMiterlimit: 10, d: "M13.6,8.5L9.5,4.3C9,3.9,8.3,3.9,7.8,4.3L4.7,7.5 C4,8.1,3.8,9.1,4.1,9.9c0.8,2.3,2.9,6.9,7,11s8.7,6.1,11,7c0.9,0.3,1.8,0.1,2.5-0.5l3.1-3.1c0.5-0.5,0.5-1.2,0-1.7l-4.1-4.1 c-0.5-0.5-1.2-0.5-1.7,0l-2.5,2.5c0,0-2.8-1.2-5-3.3s-3.3-5-3.3-5l2.5-2.5C14.1,9.7,14.1,8.9,13.6,8.5z" }) }));
4936
4954
  const GuestIcon = ({ ...props }) => (jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 256 256", width: "256", height: "256", children: [jsx("rect", { width: "256", height: "256", fill: "none" }), jsx("circle", { cx: "128", cy: "96", r: "64", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "16" }), jsx("path", { d: "M32,216c19.37-33.47,54.55-56,96-56s76.63,22.53,96,56", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "16" })] }));
4937
4955
  const EyeIcon = ({ ...props }) => (jsxs("svg", { width: "800", height: "800", fill: "none", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("path", { d: "m15.001 12c0 1.6569-1.3431 3-3 3-1.6568 0-3-1.3431-3-3s1.3432-3 3-3c1.6569 0 3 1.3431 3 3z", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2 }), jsx("path", { d: "m12.001 5c-4.4777 0-8.2679 2.9429-9.5422 7 1.2743 4.0571 5.0646 7 9.5422 7 4.4776 0 8.2679-2.9429 9.5422-7-1.2743-4.0571-5.0646-7-9.5422-7z", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2 })] }));
4938
4956
  const EyeOffIcon = ({ ...props }) => (jsx("svg", { width: "800", height: "800", fill: "none", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "m2.999 3 18 18m-11.156-11.086c-0.52264 0.53996-0.84428 1.2756-0.84428 2.0864 0 1.6569 1.3432 3 3 3 0.8225 0 1.5677-0.331 2.1096-0.867m-7.6096-7.4858c-1.8993 1.2532-3.346 3.1368-4.042 5.3528 1.2742 4.0571 5.0646 7 9.5422 7 1.9889 0 3.8422-0.5806 5.3996-1.5816m-6.3998-12.369c0.329-0.03266 0.6627-0.04939 1.0002-0.04939 4.4777 0 8.268 2.9429 9.5422 7-0.2807 0.894-0.6837 1.7338-1.1892 2.5", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2 }) }));
@@ -5631,7 +5649,7 @@ const FitText = ({ children, maxFontSize = 100, minFontSize = 70, justifyContent
5631
5649
  };
5632
5650
  FitText.displayName = 'FitText';
5633
5651
 
5634
- const OPENFORT_VERSION = '0.1.13';
5652
+ const OPENFORT_VERSION = '0.2.0';
5635
5653
 
5636
5654
  const Portal = (props) => {
5637
5655
  props = {
@@ -5668,7 +5686,7 @@ const PageContentStyle = styled(motion.div) `
5668
5686
  padding-top: 48px;
5669
5687
  `;
5670
5688
 
5671
- const ErrorMessage$1 = styled(motion.div) `
5689
+ const ErrorMessage$2 = styled(motion.div) `
5672
5690
  z-index: -1;
5673
5691
  pointer-events: auto;
5674
5692
  position: absolute;
@@ -5829,6 +5847,8 @@ const ModalBody = styled.div `
5829
5847
  color: ${(props) => {
5830
5848
  if (props.$error)
5831
5849
  return 'var(--ck-body-color-danger)';
5850
+ if (props.$valid)
5851
+ return 'var(--ck-body-color-valid)';
5832
5852
  return 'var(--ck-body-color-muted)';
5833
5853
  }};
5834
5854
  strong {
@@ -6461,8 +6481,6 @@ onInfo, }) => {
6461
6481
  return 'Reset your password'; // TODO: Localize
6462
6482
  case routes.EMAIL_VERIFICATION:
6463
6483
  return 'Email Verification'; // TODO: Localize
6464
- case routes.SOCIAL_PROVIDERS:
6465
- return 'Other socials'; // TODO: Localize
6466
6484
  case routes.CONNECT:
6467
6485
  if (shouldUseQrcode()) {
6468
6486
  return isWalletConnectConnector((_a = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _a === void 0 ? void 0 : _a.id)
@@ -6501,7 +6519,7 @@ onInfo, }) => {
6501
6519
  width: 'var(--width)',
6502
6520
  zIndex: 9,
6503
6521
  transition: 'width 200ms ease',
6504
- } }), jsxs(BoxContainer, { className: `${rendered && 'active'}`, children: [jsx(AnimatePresence, { initial: false, children: context.errorMessage && (jsxs(ErrorMessage$1, { initial: { y: '10%', x: '-50%' }, animate: { y: '-100%' }, exit: { y: '100%' }, transition: { duration: 0.2, ease: 'easeInOut' }, children: [jsx("span", { children: context.errorMessage }), jsx("button", { type: "button", "aria-label": flattenChildren(locales.close).toString(), style: {
6522
+ } }), jsxs(BoxContainer, { className: `${rendered && 'active'}`, children: [jsx(AnimatePresence, { initial: false, children: context.errorMessage && (jsxs(ErrorMessage$2, { initial: { y: '10%', x: '-50%' }, animate: { y: '-100%' }, exit: { y: '100%' }, transition: { duration: 0.2, ease: 'easeInOut' }, children: [jsx("span", { children: context.errorMessage }), jsx("button", { type: "button", "aria-label": flattenChildren(locales.close).toString(), style: {
6505
6523
  position: 'absolute',
6506
6524
  right: 24,
6507
6525
  top: 24,
@@ -6909,7 +6927,7 @@ const transition = {
6909
6927
  ease: [0.175, 0.885, 0.32, 0.98],
6910
6928
  };
6911
6929
  const Button = ({ className, children, variant = 'secondary', // unique aspect to how we're handling buttons
6912
- disabled, icon, iconPosition = 'left', roundedIcon, waiting, arrow, download, href, style, onClick, textAlign, title, }) => {
6930
+ disabled, icon, iconPosition = 'left', roundedIcon, waiting, arrow, download, href, style, onClick, textAlign, title, fitText = true, }) => {
6913
6931
  const key = typeof children === 'string' ? children : flattenChildren(children).join(''); // Need to generate a string for the key so we can automatically animate between content
6914
6932
  const hrefUrl = href && (typeof href === 'string' ? href : flattenChildren(href).join('')); // Need to have a flat string for the href
6915
6933
  return (jsx(ButtonContainer, { className: className, as: href ? 'a' : undefined, onClick: (event) => {
@@ -6928,17 +6946,17 @@ disabled, icon, iconPosition = 'left', roundedIcon, waiting, arrow, download, hr
6928
6946
  }, transition: {
6929
6947
  ...transition,
6930
6948
  delay: 0.2,
6931
- }, children: [icon && iconPosition === 'left' && jsx(IconContainer$2, { "$rounded": roundedIcon, children: icon }), download && (jsx(DownloadArrow, { children: jsx(DownloadArrowInner, { children: jsxs(Arrow, { width: "13", height: "12", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx(ArrowLine, { stroke: "currentColor", x1: "1", y1: "6", x2: "12", y2: "6", strokeWidth: "var(--stroke-width)", strokeLinecap: "round" }), jsx(ArrowChevron, { stroke: "currentColor", d: "M7.51431 1.5L11.757 5.74264M7.5 10.4858L11.7426 6.24314", strokeWidth: "var(--stroke-width)", strokeLinecap: "round" })] }) }) })), jsx(InnerContainer, { style: { paddingLeft: arrow ? 6 : 0 }, children: jsx(FitText, { justifyContent: textAlign, children: children }) }), icon && iconPosition === 'right' && jsx(IconContainer$2, { "$rounded": roundedIcon, children: icon }), arrow && (jsxs(Arrow, { width: "13", height: "12", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx(ArrowLine, { stroke: "currentColor", x1: "1", y1: "6", x2: "12", y2: "6", strokeWidth: "2", strokeLinecap: "round" }), jsx(ArrowChevron, { stroke: "currentColor", d: "M7.51431 1.5L11.757 5.74264M7.5 10.4858L11.7426 6.24314", strokeWidth: "2", strokeLinecap: "round" })] }))] }, key), waiting && (jsx(SpinnerContainer$2, { children: jsx(Spinner$3, {}) }))] }) }));
6949
+ }, children: [icon && iconPosition === 'left' && jsx(IconContainer$2, { "$rounded": roundedIcon, children: icon }), download && (jsx(DownloadArrow, { children: jsx(DownloadArrowInner, { children: jsxs(Arrow, { width: "13", height: "12", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx(ArrowLine, { stroke: "currentColor", x1: "1", y1: "6", x2: "12", y2: "6", strokeWidth: "var(--stroke-width)", strokeLinecap: "round" }), jsx(ArrowChevron, { stroke: "currentColor", d: "M7.51431 1.5L11.757 5.74264M7.5 10.4858L11.7426 6.24314", strokeWidth: "var(--stroke-width)", strokeLinecap: "round" })] }) }) })), jsx(InnerContainer, { style: { paddingLeft: arrow ? 6 : 0 }, children: fitText ? jsx(FitText, { justifyContent: textAlign, children: children }) : children }), icon && iconPosition === 'right' && jsx(IconContainer$2, { "$rounded": roundedIcon, children: icon }), arrow && (jsxs(Arrow, { width: "13", height: "12", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx(ArrowLine, { stroke: "currentColor", x1: "1", y1: "6", x2: "12", y2: "6", strokeWidth: "2", strokeLinecap: "round" }), jsx(ArrowChevron, { stroke: "currentColor", d: "M7.51431 1.5L11.757 5.74264M7.5 10.4858L11.7426 6.24314", strokeWidth: "2", strokeLinecap: "round" })] }))] }, key), waiting && (jsx(SpinnerContainer$2, { children: jsx(Spinner$3, {}) }))] }) }));
6932
6950
  };
6933
6951
 
6934
- var OpenfortErrorType;
6935
- (function (OpenfortErrorType) {
6936
- OpenfortErrorType["AUTHENTICATION_ERROR"] = "AUTHENTICATION_ERROR";
6937
- OpenfortErrorType["WALLET_ERROR"] = "WALLET_ERROR";
6938
- OpenfortErrorType["CONFIGURATION_ERROR"] = "CONFIGURATION_ERROR";
6939
- OpenfortErrorType["VALIDATION_ERROR"] = "VALIDATION_ERROR";
6940
- OpenfortErrorType["UNEXPECTED_ERROR"] = "UNEXPECTED_ERROR";
6941
- })(OpenfortErrorType || (OpenfortErrorType = {}));
6952
+ var OpenfortReactErrorType;
6953
+ (function (OpenfortReactErrorType) {
6954
+ OpenfortReactErrorType["AUTHENTICATION_ERROR"] = "AUTHENTICATION_ERROR";
6955
+ OpenfortReactErrorType["WALLET_ERROR"] = "WALLET_ERROR";
6956
+ OpenfortReactErrorType["CONFIGURATION_ERROR"] = "CONFIGURATION_ERROR";
6957
+ OpenfortReactErrorType["VALIDATION_ERROR"] = "VALIDATION_ERROR";
6958
+ OpenfortReactErrorType["UNEXPECTED_ERROR"] = "UNEXPECTED_ERROR";
6959
+ })(OpenfortReactErrorType || (OpenfortReactErrorType = {}));
6942
6960
  class OpenfortError extends Error {
6943
6961
  constructor(message, type, data) {
6944
6962
  if ((data === null || data === void 0 ? void 0 : data.error) instanceof OpenfortError) {
@@ -6984,7 +7002,7 @@ const mapStatus = (status) => {
6984
7002
  isLoading: status.status === 'loading',
6985
7003
  isError: status.status === 'error',
6986
7004
  isSuccess: status.status === 'success',
6987
- error: status.error,
7005
+ error: 'error' in status ? status.error : undefined,
6988
7006
  };
6989
7007
  };
6990
7008
 
@@ -7066,7 +7084,7 @@ function useSignOut(hookOptions = {}) {
7066
7084
  });
7067
7085
  }
7068
7086
  catch (e) {
7069
- const error = new OpenfortError('Failed to sign out', OpenfortErrorType.AUTHENTICATION_ERROR, { error: e });
7087
+ const error = new OpenfortError('Failed to sign out', OpenfortReactErrorType.AUTHENTICATION_ERROR, { error: e });
7070
7088
  setStatus({
7071
7089
  status: 'error',
7072
7090
  error,
@@ -7592,7 +7610,7 @@ const useWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000 } = {}) =
7592
7610
  queryKey: ['wallet-assets', chainId, customAssetsToFetch, address],
7593
7611
  queryFn: async () => {
7594
7612
  if (!walletClient) {
7595
- throw new OpenfortError('No wallet client available', OpenfortErrorType.UNEXPECTED_ERROR, {
7613
+ throw new OpenfortError('No wallet client available', OpenfortReactErrorType.UNEXPECTED_ERROR, {
7596
7614
  error: new Error('Wallet client not initialized'),
7597
7615
  });
7598
7616
  }
@@ -7649,7 +7667,7 @@ const useWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000 } = {}) =
7649
7667
  };
7650
7668
  }
7651
7669
  else {
7652
- throw new OpenfortError('Unsupported asset type', OpenfortErrorType.UNEXPECTED_ERROR, { asset: a });
7670
+ throw new OpenfortError('Unsupported asset type', OpenfortReactErrorType.UNEXPECTED_ERROR, { asset: a });
7653
7671
  }
7654
7672
  return asset;
7655
7673
  });
@@ -7692,7 +7710,7 @@ const useWalletAssets = ({ assets: hookCustomAssets, staleTime = 30000 } = {}) =
7692
7710
  if (error instanceof OpenfortError) {
7693
7711
  return error;
7694
7712
  }
7695
- return new OpenfortError('Failed to fetch wallet assets', OpenfortErrorType.UNEXPECTED_ERROR, { error });
7713
+ return new OpenfortError('Failed to fetch wallet assets', OpenfortReactErrorType.UNEXPECTED_ERROR, { error });
7696
7714
  }, [error]);
7697
7715
  return {
7698
7716
  data: data !== null && data !== void 0 ? data : null,
@@ -10363,12 +10381,12 @@ const Content = styled(motion.div) `
10363
10381
  gap: 12px;
10364
10382
  }
10365
10383
  `;
10366
- const dist$1 = 2;
10367
- const shakeKeyframes$1 = keyframes `
10384
+ const dist$2 = 2;
10385
+ const shakeKeyframes$2 = keyframes `
10368
10386
  0%{ transform:none; }
10369
- 25%{ transform:translateX(${dist$1}px); }
10370
- 50%{ transform:translateX(-${dist$1}px); }
10371
- 75%{ transform:translateX(${dist$1}px); }
10387
+ 25%{ transform:translateX(${dist$2}px); }
10388
+ 50%{ transform:translateX(-${dist$2}px); }
10389
+ 75%{ transform:translateX(${dist$2}px); }
10372
10390
  100%{ transform:none; }
10373
10391
  `;
10374
10392
  const outlineKeyframes$1 = keyframes `
@@ -10410,7 +10428,7 @@ const ConnectingAnimation$1 = styled(motion.div) `
10410
10428
  }
10411
10429
  ${(props) => props.$shake &&
10412
10430
  css `
10413
- animation: ${shakeKeyframes$1} 220ms ease-out both;
10431
+ animation: ${shakeKeyframes$2} 220ms ease-out both;
10414
10432
  &:before {
10415
10433
  animation: ${outlineKeyframes$1} 220ms ease-out 750ms both;
10416
10434
  }
@@ -10493,12 +10511,12 @@ justify-content: center;
10493
10511
  margin: 10px auto 16px;
10494
10512
  height: 120px;
10495
10513
  `;
10496
- const dist = 2;
10497
- const shakeKeyframes = keyframes `
10514
+ const dist$1 = 2;
10515
+ const shakeKeyframes$1 = keyframes `
10498
10516
  0%{ transform:none; }
10499
- 25%{ transform:translateX(${dist}px); }
10500
- 50%{ transform:translateX(-${dist}px); }
10501
- 75%{ transform:translateX(${dist}px); }
10517
+ 25%{ transform:translateX(${dist$1}px); }
10518
+ 50%{ transform:translateX(-${dist$1}px); }
10519
+ 75%{ transform:translateX(${dist$1}px); }
10502
10520
  100%{ transform:none; }
10503
10521
  `;
10504
10522
  const outlineKeyframes = keyframes `
@@ -10525,7 +10543,7 @@ const ConnectingAnimation = styled(motion.div) `
10525
10543
  `}
10526
10544
  ${(props) => props.$shake &&
10527
10545
  css `
10528
- animation: ${shakeKeyframes} 220ms ease-out both;
10546
+ animation: ${shakeKeyframes$1} 220ms ease-out both;
10529
10547
  &:before {
10530
10548
  animation: ${outlineKeyframes} 220ms ease-out both;
10531
10549
  }
@@ -11278,7 +11296,7 @@ const Connectors = ({ logoutOnBack }) => {
11278
11296
  * console.log('User is authenticated:', userHook.user);
11279
11297
  * console.log('User ID:', userHook.user.id);
11280
11298
  * console.log('User email:', userHook.user.email);
11281
- * console.log('Linked accounts:', userHook.user.linkedAccounts);
11299
+ * console.log('Linked accounts:', userHook.linkedAccounts);
11282
11300
  * } else {
11283
11301
  * console.log('User is not authenticated');
11284
11302
  * }
@@ -11305,7 +11323,7 @@ const Connectors = ({ logoutOnBack }) => {
11305
11323
  * ```
11306
11324
  */
11307
11325
  function useUser() {
11308
- const { user, client, embeddedState } = useOpenfortCore();
11326
+ const { user, client, embeddedState, linkedAccounts } = useOpenfortCore();
11309
11327
  const getAccessTokenAndUpdate = useCallback(async () => {
11310
11328
  try {
11311
11329
  await client.validateAndRefreshToken();
@@ -11328,6 +11346,7 @@ function useUser() {
11328
11346
  }, [client]);
11329
11347
  return {
11330
11348
  user,
11349
+ linkedAccounts,
11331
11350
  isAuthenticated: embeddedState !== EmbeddedState.NONE && embeddedState !== EmbeddedState.UNAUTHENTICATED,
11332
11351
  getAccessToken: getAccessTokenAndUpdate,
11333
11352
  validateAndRefreshToken: validateAndRefresh,
@@ -11423,7 +11442,7 @@ const mapWalletStatus = (status) => {
11423
11442
  */
11424
11443
  function useWallets(hookOptions = {}) {
11425
11444
  const { client, embeddedAccounts, isLoadingAccounts: isLoadingWallets, updateEmbeddedAccounts } = useOpenfortCore();
11426
- const { user } = useUser();
11445
+ const { linkedAccounts } = useUser();
11427
11446
  const { walletConfig, setOpen, setRoute, setConnector, uiConfig } = useOpenfort();
11428
11447
  const { connector, isConnected, address } = useAccount();
11429
11448
  const chainId = useChainId();
@@ -11435,7 +11454,7 @@ function useWallets(hookOptions = {}) {
11435
11454
  const { connect } = useConnect({
11436
11455
  mutation: {
11437
11456
  onError: (e) => {
11438
- const error = new OpenfortError('Failed to connect with wallet: ', OpenfortErrorType.AUTHENTICATION_ERROR, e);
11457
+ const error = new OpenfortError('Failed to connect with wallet: ', OpenfortReactErrorType.AUTHENTICATION_ERROR, e);
11439
11458
  setStatus({
11440
11459
  status: 'error',
11441
11460
  error,
@@ -11452,7 +11471,7 @@ function useWallets(hookOptions = {}) {
11452
11471
  !data.accounts.some((a) => { var _a; return a.toLowerCase() === ((_a = connectToConnector.address) === null || _a === void 0 ? void 0 : _a.toLowerCase()); })) {
11453
11472
  setStatus({
11454
11473
  status: 'error',
11455
- error: new OpenfortError('Failed to connect with wallet: Address mismatch', OpenfortErrorType.AUTHENTICATION_ERROR),
11474
+ error: new OpenfortError('Failed to connect with wallet: Address mismatch', OpenfortReactErrorType.AUTHENTICATION_ERROR),
11456
11475
  });
11457
11476
  disconnect();
11458
11477
  return;
@@ -11487,7 +11506,7 @@ function useWallets(hookOptions = {}) {
11487
11506
  case RecoveryMethod.AUTOMATIC: {
11488
11507
  const accessToken = await client.getAccessToken();
11489
11508
  if (!accessToken) {
11490
- throw new OpenfortError('Openfort access token not found', OpenfortErrorType.AUTHENTICATION_ERROR);
11509
+ throw new OpenfortError('Openfort access token not found', OpenfortReactErrorType.AUTHENTICATION_ERROR);
11491
11510
  }
11492
11511
  return {
11493
11512
  recoveryMethod: RecoveryMethod.AUTOMATIC,
@@ -11498,7 +11517,7 @@ function useWallets(hookOptions = {}) {
11498
11517
  }
11499
11518
  case RecoveryMethod.PASSWORD:
11500
11519
  if (!recovery.password) {
11501
- throw new OpenfortError('Please enter your password', OpenfortErrorType.VALIDATION_ERROR);
11520
+ throw new OpenfortError('Please enter your password', OpenfortReactErrorType.VALIDATION_ERROR);
11502
11521
  }
11503
11522
  return {
11504
11523
  recoveryMethod: RecoveryMethod.PASSWORD,
@@ -11513,13 +11532,13 @@ function useWallets(hookOptions = {}) {
11513
11532
  if (!walletAddress) {
11514
11533
  walletAddress = (_a = embeddedAccounts.find((w) => w.recoveryMethod === RecoveryMethod.PASSKEY)) === null || _a === void 0 ? void 0 : _a.address;
11515
11534
  if (!walletAddress) {
11516
- throw new OpenfortError('No wallet address provided and no embedded wallet with passkey recovery found', OpenfortErrorType.VALIDATION_ERROR);
11535
+ throw new OpenfortError('No wallet address provided and no embedded wallet with passkey recovery found', OpenfortReactErrorType.VALIDATION_ERROR);
11517
11536
  }
11518
11537
  }
11519
11538
  const details = (_b = embeddedAccounts.find((w) => w.address.toLowerCase() === (walletAddress === null || walletAddress === void 0 ? void 0 : walletAddress.toLowerCase()) && w.recoveryMethod === RecoveryMethod.PASSKEY)) === null || _b === void 0 ? void 0 : _b.recoveryMethodDetails;
11520
11539
  const passkeyId = details === null || details === void 0 ? void 0 : details.passkeyId;
11521
11540
  if (!passkeyId) {
11522
- throw new OpenfortError('No passkey details found for the wallet', OpenfortErrorType.VALIDATION_ERROR);
11541
+ throw new OpenfortError('No passkey details found for the wallet', OpenfortReactErrorType.VALIDATION_ERROR);
11523
11542
  }
11524
11543
  return {
11525
11544
  recoveryMethod: RecoveryMethod.PASSKEY,
@@ -11529,19 +11548,19 @@ function useWallets(hookOptions = {}) {
11529
11548
  };
11530
11549
  }
11531
11550
  default:
11532
- throw new OpenfortError('Invalid recovery method', OpenfortErrorType.VALIDATION_ERROR);
11551
+ throw new OpenfortError('Invalid recovery method', OpenfortReactErrorType.VALIDATION_ERROR);
11533
11552
  }
11534
11553
  }, [walletConfig, getEncryptionSession]);
11535
11554
  const userLinkedWalletConnectors = useMemo(() => {
11536
- const userWallets = user
11537
- ? user.linkedAccounts
11555
+ const userWallets = linkedAccounts
11556
+ ? linkedAccounts
11538
11557
  .filter((linkedAccount) => linkedAccount.provider === UIAuthProvider.WALLET)
11539
11558
  .map((linkedAccount) => {
11540
11559
  // For connector wallets (e.g. Metamask, Rabby, etc.)
11541
11560
  const wallet = availableWallets.find((c) => c.connector.id === linkedAccount.walletClientType);
11542
11561
  return {
11543
11562
  accounts: [],
11544
- address: linkedAccount.address,
11563
+ address: linkedAccount.accountId,
11545
11564
  connectorType: linkedAccount.connectorType,
11546
11565
  walletClientType: linkedAccount.walletClientType,
11547
11566
  id: (wallet === null || wallet === void 0 ? void 0 : wallet.id) || linkedAccount.walletClientType || 'unknown',
@@ -11551,7 +11570,7 @@ function useWallets(hookOptions = {}) {
11551
11570
  })
11552
11571
  : [];
11553
11572
  return userWallets;
11554
- }, [user === null || user === void 0 ? void 0 : user.linkedAccounts, embeddedAccounts]);
11573
+ }, [linkedAccounts, embeddedAccounts]);
11555
11574
  const userEmbeddedWallets = useMemo(() => {
11556
11575
  const newRawWallets = [];
11557
11576
  embeddedAccounts === null || embeddedAccounts === void 0 ? void 0 : embeddedAccounts.forEach((embeddedAccount) => {
@@ -11599,7 +11618,7 @@ function useWallets(hookOptions = {}) {
11599
11618
  const wallet = availableWallets.find((c) => c.id === optionsObject.walletId);
11600
11619
  if (!wallet) {
11601
11620
  logger.log('Connector not found', connector);
11602
- return { error: new OpenfortError('Connector not found', OpenfortErrorType.WALLET_ERROR) };
11621
+ return { error: new OpenfortError('Connector not found', OpenfortReactErrorType.WALLET_ERROR) };
11603
11622
  }
11604
11623
  logger.log('Connecting to', wallet.connector);
11605
11624
  connector = wallet.connector;
@@ -11609,7 +11628,7 @@ function useWallets(hookOptions = {}) {
11609
11628
  }
11610
11629
  if (!connector) {
11611
11630
  logger.log('Connector not found', availableWallets, optionsObject.walletId);
11612
- return { error: new OpenfortError('Connector not found', OpenfortErrorType.WALLET_ERROR) };
11631
+ return { error: new OpenfortError('Connector not found', OpenfortReactErrorType.WALLET_ERROR) };
11613
11632
  }
11614
11633
  if ((activeWallet === null || activeWallet === void 0 ? void 0 : activeWallet.id) === connector.id && (address === null || address === void 0 ? void 0 : address.toLowerCase()) === ((_a = optionsObject.address) === null || _a === void 0 ? void 0 : _a.toLowerCase())) {
11615
11634
  logger.log(`Already connected to ${connector.id} with address ${address}, skipping connection`);
@@ -11621,7 +11640,7 @@ function useWallets(hookOptions = {}) {
11621
11640
  if (!walletToConnect) {
11622
11641
  logger.log('Wallet not found', connector);
11623
11642
  return onError({
11624
- error: new OpenfortError('Wallet not found', OpenfortErrorType.AUTHENTICATION_ERROR),
11643
+ error: new OpenfortError('Wallet not found', OpenfortReactErrorType.AUTHENTICATION_ERROR),
11625
11644
  options: optionsObject,
11626
11645
  hookOptions,
11627
11646
  });
@@ -11651,7 +11670,7 @@ function useWallets(hookOptions = {}) {
11651
11670
  });
11652
11671
  if (!walletConfig) {
11653
11672
  return onError({
11654
- error: new OpenfortError('Embedded signer not enabled', OpenfortErrorType.WALLET_ERROR),
11673
+ error: new OpenfortError('Embedded signer not enabled', OpenfortReactErrorType.WALLET_ERROR),
11655
11674
  options: optionsObject,
11656
11675
  hookOptions,
11657
11676
  });
@@ -11686,7 +11705,7 @@ function useWallets(hookOptions = {}) {
11686
11705
  return w.address.toLowerCase() === addressToMatch && !!w.chainId;
11687
11706
  });
11688
11707
  if (!accountToRecoverInDifferentChain || !accountToRecoverInDifferentChain.chainId) {
11689
- throw new OpenfortError(`Embedded wallet not found for address ${walletAddress}`, OpenfortErrorType.WALLET_ERROR);
11708
+ throw new OpenfortError(`Embedded wallet not found for address ${walletAddress}`, OpenfortReactErrorType.WALLET_ERROR);
11690
11709
  }
11691
11710
  logger.log(`Found embedded wallet for address ${walletAddress} in different chain ${accountToRecoverInDifferentChain.chainId}.`);
11692
11711
  hasToSwitchChain = true;
@@ -11697,7 +11716,7 @@ function useWallets(hookOptions = {}) {
11697
11716
  accountToRecover.recoveryMethod &&
11698
11717
  optionsObject.recovery.recoveryMethod !== accountToRecover.recoveryMethod) {
11699
11718
  logger.log('Recovery method does not match', optionsObject.recovery.recoveryMethod, accountToRecover.recoveryMethod);
11700
- throw new OpenfortError("The recovery method you entered is incorrect and does not match the wallet's recovery method", OpenfortErrorType.WALLET_ERROR);
11719
+ throw new OpenfortError("The recovery method you entered is incorrect and does not match the wallet's recovery method", OpenfortReactErrorType.WALLET_ERROR);
11701
11720
  }
11702
11721
  const recovery = {
11703
11722
  recoveryMethod: (_c = accountToRecover.recoveryMethod) !== null && _c !== void 0 ? _c : RecoveryMethod.AUTOMATIC,
@@ -11715,7 +11734,7 @@ function useWallets(hookOptions = {}) {
11715
11734
  if ((walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.accountType) === AccountTypeEnum.EOA) {
11716
11735
  accountToRecover = embeddedAccounts.find((w) => w.accountType === AccountTypeEnum.EOA);
11717
11736
  if (!accountToRecover) {
11718
- throw new OpenfortError('No embedded wallet found with type EOA', OpenfortErrorType.WALLET_ERROR);
11737
+ throw new OpenfortError('No embedded wallet found with type EOA', OpenfortReactErrorType.WALLET_ERROR);
11719
11738
  }
11720
11739
  }
11721
11740
  else {
@@ -11723,7 +11742,7 @@ function useWallets(hookOptions = {}) {
11723
11742
  if (!accountToRecover) {
11724
11743
  // Here it should check if there is a wallet that can recover in another chain and recover it in the current chain (its a different account so its not supported yet)
11725
11744
  // TODO: Connect to wallet in the other chain and then switch chain
11726
- throw new OpenfortError('No embedded wallet found for the current chain', OpenfortErrorType.WALLET_ERROR);
11745
+ throw new OpenfortError('No embedded wallet found for the current chain', OpenfortReactErrorType.WALLET_ERROR);
11727
11746
  }
11728
11747
  }
11729
11748
  logger.log('Found embedded wallet to recover (without walletAddress)', accountToRecover);
@@ -11739,7 +11758,7 @@ function useWallets(hookOptions = {}) {
11739
11758
  walletAddress = accountToRecover.address;
11740
11759
  }
11741
11760
  if (!embeddedAccount) {
11742
- throw new OpenfortError('Failed to recover embedded wallet', OpenfortErrorType.WALLET_ERROR);
11761
+ throw new OpenfortError('Failed to recover embedded wallet', OpenfortReactErrorType.WALLET_ERROR);
11743
11762
  }
11744
11763
  setStatus({
11745
11764
  status: 'success',
@@ -11763,16 +11782,16 @@ function useWallets(hookOptions = {}) {
11763
11782
  catch (err) {
11764
11783
  let error;
11765
11784
  if (err instanceof MissingRecoveryPasswordError) {
11766
- error = new OpenfortError('Missing recovery password', OpenfortErrorType.WALLET_ERROR);
11785
+ error = new OpenfortError('Missing recovery password', OpenfortReactErrorType.WALLET_ERROR);
11767
11786
  }
11768
11787
  else if (err instanceof OpenfortError) {
11769
11788
  error = err;
11770
11789
  }
11771
11790
  else if (typeof err === 'string') {
11772
- error = new OpenfortError(err, OpenfortErrorType.WALLET_ERROR);
11791
+ error = new OpenfortError(err, OpenfortReactErrorType.WALLET_ERROR);
11773
11792
  }
11774
11793
  else {
11775
- error = new OpenfortError('Failed to recover embedded wallet', OpenfortErrorType.WALLET_ERROR, {
11794
+ error = new OpenfortError('Failed to recover embedded wallet', OpenfortReactErrorType.WALLET_ERROR, {
11776
11795
  error: err,
11777
11796
  });
11778
11797
  if (error.message === 'Wrong recovery password for this embedded signer') {
@@ -11830,10 +11849,10 @@ function useWallets(hookOptions = {}) {
11830
11849
  try {
11831
11850
  const accessToken = await client.getAccessToken();
11832
11851
  if (!accessToken) {
11833
- throw new OpenfortError('Openfort access token not found', OpenfortErrorType.WALLET_ERROR);
11852
+ throw new OpenfortError('Openfort access token not found', OpenfortReactErrorType.WALLET_ERROR);
11834
11853
  }
11835
11854
  if (!walletConfig) {
11836
- throw new OpenfortError('Embedded signer not enabled', OpenfortErrorType.WALLET_ERROR);
11855
+ throw new OpenfortError('Embedded signer not enabled', OpenfortReactErrorType.WALLET_ERROR);
11837
11856
  }
11838
11857
  const recoveryParams = await parseWalletRecovery(recovery);
11839
11858
  const accountType = (options === null || options === void 0 ? void 0 : options.accountType) || (walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.accountType) || AccountTypeEnum.SMART_ACCOUNT;
@@ -11867,7 +11886,7 @@ function useWallets(hookOptions = {}) {
11867
11886
  const errorObj = e instanceof Error ? e : new Error('Failed to create wallet');
11868
11887
  const error = e instanceof OpenfortError
11869
11888
  ? e
11870
- : new OpenfortError('Failed to create wallet', OpenfortErrorType.WALLET_ERROR, { error: errorObj });
11889
+ : new OpenfortError('Failed to create wallet', OpenfortReactErrorType.WALLET_ERROR, { error: errorObj });
11871
11890
  setStatus({
11872
11891
  status: 'error',
11873
11892
  error,
@@ -11910,7 +11929,7 @@ function useWallets(hookOptions = {}) {
11910
11929
  return onError({
11911
11930
  hookOptions,
11912
11931
  options: params,
11913
- error: new OpenfortError('Failed to set wallet recovery', OpenfortErrorType.WALLET_ERROR, {
11932
+ error: new OpenfortError('Failed to set wallet recovery', OpenfortReactErrorType.WALLET_ERROR, {
11914
11933
  error: errorObj,
11915
11934
  }),
11916
11935
  });
@@ -12067,7 +12086,7 @@ const useGuestAuth = (hookOptions = {}) => {
12067
12086
  status: 'loading',
12068
12087
  });
12069
12088
  const result = await client.auth.signUpGuest();
12070
- const user = result.player;
12089
+ const user = result.user;
12071
12090
  await updateUser(user);
12072
12091
  const { wallet } = await tryUseWallet({
12073
12092
  logoutOnError: (_a = options.logoutOnError) !== null && _a !== void 0 ? _a : hookOptions.logoutOnError,
@@ -12083,7 +12102,7 @@ const useGuestAuth = (hookOptions = {}) => {
12083
12102
  });
12084
12103
  }
12085
12104
  catch (error) {
12086
- const openfortError = new OpenfortError('Failed to signup guest', OpenfortErrorType.AUTHENTICATION_ERROR, {
12105
+ const openfortError = new OpenfortError('Failed to signup guest', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
12087
12106
  error,
12088
12107
  });
12089
12108
  setStatus({
@@ -12212,7 +12231,10 @@ var wave = (jsxs("svg", { "aria-hidden": "true", width: "298", height: "188", vi
12212
12231
 
12213
12232
  const Graphic = styled(motion.div) `
12214
12233
  position: relative;
12215
- margin: 16px auto 20px;
12234
+ margin-top: ${({ $marginTop }) => $marginTop !== null && $marginTop !== void 0 ? $marginTop : '16px'};
12235
+ margin-bottom: ${({ $marginBottom }) => $marginBottom !== null && $marginBottom !== void 0 ? $marginBottom : '20px'};
12236
+ margin-left: auto;
12237
+ margin-right: auto;
12216
12238
  height: ${({ $height }) => $height !== null && $height !== void 0 ? $height : '190px'};
12217
12239
  max-width: 295px;
12218
12240
  pointer-events: none;
@@ -12378,8 +12400,8 @@ const Logo$1 = styled(motion.div) `
12378
12400
  const LogoGraphic = ({ size = '100%', logo }) => {
12379
12401
  return (jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { style: { transform: `scale(${size})` }, children: logo }) }) }) }) }) }));
12380
12402
  };
12381
- const FloatingGraphic = ({ height = '130px', logoCenter, logoTopRight, logoTopLeft, logoBottomRight, logoBottomLeft, }) => {
12382
- return (jsxs(Graphic, { "$height": height, children: [jsxs(LogoGroup, { children: [jsx(LogoGraphic, { ...logoCenter }), logoTopLeft ? jsx(LogoGraphic, { ...logoTopLeft }) : jsx("div", {}), logoTopRight ? jsx(LogoGraphic, { ...logoTopRight }) : jsx("div", {}), logoBottomLeft ? jsx(LogoGraphic, { ...logoBottomLeft }) : jsx("div", {}), logoBottomRight ? jsx(LogoGraphic, { ...logoBottomRight }) : jsx("div", {})] }), jsx(GraphicBackground, { children: wave })] }));
12403
+ const FloatingGraphic = ({ height = '130px', marginBottom, marginTop, logoCenter, logoTopRight, logoTopLeft, logoBottomRight, logoBottomLeft, }) => {
12404
+ return (jsxs(Graphic, { "$height": height, "$marginBottom": marginBottom, "$marginTop": marginTop, children: [jsxs(LogoGroup, { children: [jsx(LogoGraphic, { ...logoCenter }), logoTopLeft ? jsx(LogoGraphic, { ...logoTopLeft }) : jsx("div", {}), logoTopRight ? jsx(LogoGraphic, { ...logoTopRight }) : jsx("div", {}), logoBottomLeft ? jsx(LogoGraphic, { ...logoBottomLeft }) : jsx("div", {}), logoBottomRight ? jsx(LogoGraphic, { ...logoBottomRight }) : jsx("div", {})] }), jsx(GraphicBackground, { children: wave })] }));
12383
12405
  };
12384
12406
 
12385
12407
  /**
@@ -12600,10 +12622,29 @@ const ProviderInputInner = styled.div `
12600
12622
  width: 100%;
12601
12623
  height: 100%;
12602
12624
  }
12625
+
12626
+ .react-international-phone-country-selector-button {
12627
+ padding-left: 20px;
12628
+ padding-right: 10px;
12629
+ border-radius: var(--ck-secondary-button-border-radius) 0px 0px var(--ck-secondary-button-border-radius);
12630
+ transition: all .2s ease-out;
12631
+ }
12632
+
12633
+ .react-international-phone-country-selector-dropdown {
12634
+ box-shadow: var(--ck-secondary-button-hover-box-shadow);
12635
+ }
12636
+
12637
+ .react-international-phone-country-selector-button__dropdown-arrow {
12638
+ border-top: var(--react-international-phone-country-selector-arrow-size, 4px) solid var(--react-international-phone-country-selector-arrow-color, #777) !important;
12639
+ border-right: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent !important;
12640
+ border-left: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent !important;
12641
+ margin-right: 4px;
12642
+ transition: all .1s ease-out;
12643
+ }
12603
12644
  `;
12604
12645
  const EmailInnerButton = styled(motion.button) `
12605
12646
  color: var(--ck-body-action-color);
12606
- transition: background-color 200ms ease, transform 100ms ease, color 200ms ease, transition 200ms ease;
12647
+ transition: background-color 200ms ease, transform 100ms ease, color 200ms ease, transition 200ms ease, opacity 200ms ease;
12607
12648
  border-radius: 16px;
12608
12649
 
12609
12650
  svg {
@@ -13146,6 +13187,11 @@ const DownloadApp = () => {
13146
13187
  return (jsx(PageContent, { children: jsxs(ModalContent, { style: { paddingBottom: 4, gap: 14 }, children: [downloads.redirect && jsx(CustomQRCode, { value: downloads.redirect }), !downloads.redirect && jsx(Fragment, { children: "No download link available" }), jsx(ModalBody, { style: { fontSize: 15, lineHeight: '20px', padding: '0 12px' }, children: bodycopy })] }) }));
13147
13188
  };
13148
13189
 
13190
+ const isValidEmail = (email) => {
13191
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
13192
+ return emailRegex.test(email);
13193
+ };
13194
+
13149
13195
  const buildCallbackUrl = ({ email, callbackUrl, provider, isOpen, }) => {
13150
13196
  if (callbackUrl && !callbackUrl.startsWith('http')) {
13151
13197
  callbackUrl = `${window.location.origin}${callbackUrl.startsWith('/') ? '' : '/'}${callbackUrl}`;
@@ -13161,10 +13207,6 @@ const buildCallbackUrl = ({ email, callbackUrl, provider, isOpen, }) => {
13161
13207
  return redirectUrl.toString();
13162
13208
  };
13163
13209
 
13164
- const isValidEmail = (email) => {
13165
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
13166
- return emailRegex.test(email);
13167
- };
13168
13210
  /**
13169
13211
  * Hook for email-based authentication operations
13170
13212
  *
@@ -13258,7 +13300,7 @@ const useEmailAuth = (hookOptions = {}) => {
13258
13300
  });
13259
13301
  setRequiresEmailVerification(false);
13260
13302
  if (!options.email || !options.password) {
13261
- const error = new OpenfortError('Email and password are required', OpenfortErrorType.VALIDATION_ERROR);
13303
+ const error = new OpenfortError('Email and password are required', OpenfortReactErrorType.VALIDATION_ERROR);
13262
13304
  setStatus({
13263
13305
  status: 'error',
13264
13306
  error,
@@ -13270,7 +13312,7 @@ const useEmailAuth = (hookOptions = {}) => {
13270
13312
  });
13271
13313
  }
13272
13314
  if (!isValidEmail(options.email)) {
13273
- const error = new OpenfortError('Invalid email', OpenfortErrorType.VALIDATION_ERROR);
13315
+ const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
13274
13316
  setStatus({
13275
13317
  status: 'error',
13276
13318
  error,
@@ -13313,7 +13355,7 @@ const useEmailAuth = (hookOptions = {}) => {
13313
13355
  setStatus({
13314
13356
  status: 'success',
13315
13357
  });
13316
- const user = result.player;
13358
+ const user = result.user;
13317
13359
  await updateUser();
13318
13360
  return onSuccess({
13319
13361
  data: { user, wallet },
@@ -13323,7 +13365,7 @@ const useEmailAuth = (hookOptions = {}) => {
13323
13365
  }
13324
13366
  }
13325
13367
  catch (e) {
13326
- const error = new OpenfortError('Failed to login with email and password', OpenfortErrorType.AUTHENTICATION_ERROR, { error: e });
13368
+ const error = new OpenfortError('Failed to login with email and password', OpenfortReactErrorType.AUTHENTICATION_ERROR, { error: e });
13327
13369
  setStatus({
13328
13370
  status: 'error',
13329
13371
  error: error,
@@ -13339,7 +13381,7 @@ const useEmailAuth = (hookOptions = {}) => {
13339
13381
  var _a;
13340
13382
  try {
13341
13383
  if (!isValidEmail(options.email)) {
13342
- const error = new OpenfortError('Invalid email', OpenfortErrorType.VALIDATION_ERROR);
13384
+ const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
13343
13385
  setStatus({
13344
13386
  status: 'error',
13345
13387
  error,
@@ -13374,7 +13416,7 @@ const useEmailAuth = (hookOptions = {}) => {
13374
13416
  });
13375
13417
  }
13376
13418
  catch (e) {
13377
- const error = new OpenfortError('Failed to reset password', OpenfortErrorType.AUTHENTICATION_ERROR, {
13419
+ const error = new OpenfortError('Failed to reset password', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
13378
13420
  error: e,
13379
13421
  });
13380
13422
  setStatus({
@@ -13391,7 +13433,7 @@ const useEmailAuth = (hookOptions = {}) => {
13391
13433
  const resetPassword = useCallback(async (options) => {
13392
13434
  try {
13393
13435
  if (!isValidEmail(options.email)) {
13394
- const error = new OpenfortError('Invalid email', OpenfortErrorType.VALIDATION_ERROR);
13436
+ const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
13395
13437
  setStatus({
13396
13438
  status: 'error',
13397
13439
  error,
@@ -13407,9 +13449,8 @@ const useEmailAuth = (hookOptions = {}) => {
13407
13449
  });
13408
13450
  setRequiresEmailVerification(false);
13409
13451
  await client.auth.resetPassword({
13410
- email: options.email,
13411
13452
  password: options.password,
13412
- state: options.state,
13453
+ token: options.state,
13413
13454
  });
13414
13455
  setStatus({
13415
13456
  status: 'success',
@@ -13422,7 +13463,7 @@ const useEmailAuth = (hookOptions = {}) => {
13422
13463
  });
13423
13464
  }
13424
13465
  catch (e) {
13425
- const error = new OpenfortError('Failed to reset password', OpenfortErrorType.AUTHENTICATION_ERROR, {
13466
+ const error = new OpenfortError('Failed to reset password', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
13426
13467
  error: e,
13427
13468
  });
13428
13469
  setStatus({
@@ -13440,7 +13481,7 @@ const useEmailAuth = (hookOptions = {}) => {
13440
13481
  var _a, _b, _c;
13441
13482
  try {
13442
13483
  if (!options.email || !options.password) {
13443
- const error = new OpenfortError('Email and password are required', OpenfortErrorType.VALIDATION_ERROR);
13484
+ const error = new OpenfortError('Email and password are required', OpenfortReactErrorType.VALIDATION_ERROR);
13444
13485
  setStatus({
13445
13486
  status: 'error',
13446
13487
  error,
@@ -13452,7 +13493,7 @@ const useEmailAuth = (hookOptions = {}) => {
13452
13493
  });
13453
13494
  }
13454
13495
  if (!isValidEmail(options.email)) {
13455
- const error = new OpenfortError('Invalid email', OpenfortErrorType.VALIDATION_ERROR);
13496
+ const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
13456
13497
  setStatus({
13457
13498
  status: 'error',
13458
13499
  error,
@@ -13470,47 +13511,45 @@ const useEmailAuth = (hookOptions = {}) => {
13470
13511
  const result = await client.auth.signUpWithEmailPassword({
13471
13512
  email: options.email,
13472
13513
  password: options.password,
13514
+ callbackURL: buildCallbackUrl({
13515
+ email: options.email,
13516
+ callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
13517
+ provider: 'email',
13518
+ isOpen,
13519
+ }),
13473
13520
  ...(options.name && { name: options.name }),
13474
13521
  });
13475
- if ('action' in result) {
13476
- setStatus({
13477
- status: 'awaiting-input',
13522
+ // TODO: TMP FIX
13523
+ if ('token' in result && result.token !== null) {
13524
+ const { wallet } = await tryUseWallet({
13525
+ logoutOnError: (_b = options.logoutOnError) !== null && _b !== void 0 ? _b : hookOptions.logoutOnError,
13526
+ recoverWalletAutomatically: (_c = options.recoverWalletAutomatically) !== null && _c !== void 0 ? _c : hookOptions.recoverWalletAutomatically,
13478
13527
  });
13479
- client.auth.requestEmailVerification({
13480
- email: options.email,
13481
- redirectUrl: buildCallbackUrl({
13482
- email: options.email,
13483
- callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
13484
- provider: 'email',
13485
- isOpen,
13486
- }),
13528
+ setStatus({
13529
+ status: 'success',
13487
13530
  });
13488
- setRequiresEmailVerification(true);
13531
+ const user = result.user;
13532
+ await updateUser(user);
13489
13533
  return onSuccess({
13490
- data: { requiresEmailVerification: true },
13534
+ data: { user, wallet },
13491
13535
  hookOptions,
13492
13536
  options,
13493
13537
  });
13494
13538
  }
13495
13539
  else {
13496
- const { wallet } = await tryUseWallet({
13497
- logoutOnError: (_b = options.logoutOnError) !== null && _b !== void 0 ? _b : hookOptions.logoutOnError,
13498
- recoverWalletAutomatically: (_c = options.recoverWalletAutomatically) !== null && _c !== void 0 ? _c : hookOptions.recoverWalletAutomatically,
13499
- });
13500
13540
  setStatus({
13501
- status: 'success',
13541
+ status: 'awaiting-input',
13502
13542
  });
13503
- const user = result.player;
13504
- await updateUser(user);
13543
+ setRequiresEmailVerification(true);
13505
13544
  return onSuccess({
13506
- data: { user, wallet },
13545
+ data: { requiresEmailVerification: true },
13507
13546
  hookOptions,
13508
13547
  options,
13509
13548
  });
13510
13549
  }
13511
13550
  }
13512
13551
  catch (e) {
13513
- const error = new OpenfortError('Failed to login with email and password', OpenfortErrorType.AUTHENTICATION_ERROR, { error: e });
13552
+ const error = new OpenfortError('Failed to login with email and password', OpenfortReactErrorType.AUTHENTICATION_ERROR, { error: e });
13514
13553
  setStatus({
13515
13554
  status: 'error',
13516
13555
  error,
@@ -13526,7 +13565,7 @@ const useEmailAuth = (hookOptions = {}) => {
13526
13565
  var _a;
13527
13566
  try {
13528
13567
  if (!isValidEmail(options.email)) {
13529
- const error = new OpenfortError('Invalid email', OpenfortErrorType.VALIDATION_ERROR);
13568
+ const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
13530
13569
  setStatus({
13531
13570
  status: 'error',
13532
13571
  error,
@@ -13541,7 +13580,7 @@ const useEmailAuth = (hookOptions = {}) => {
13541
13580
  const authToken = await client.getAccessToken();
13542
13581
  if (!authToken) {
13543
13582
  logger.log('No token found');
13544
- const error = new OpenfortError('No token found', OpenfortErrorType.AUTHENTICATION_ERROR);
13583
+ const error = new OpenfortError('No token found', OpenfortReactErrorType.AUTHENTICATION_ERROR);
13545
13584
  setStatus({
13546
13585
  status: 'error',
13547
13586
  error,
@@ -13552,43 +13591,29 @@ const useEmailAuth = (hookOptions = {}) => {
13552
13591
  error,
13553
13592
  });
13554
13593
  }
13555
- const result = await client.auth.linkEmailPassword({
13594
+ await client.auth.addEmail({
13595
+ // name: options.name || '',
13556
13596
  email: options.email,
13557
- password: options.password,
13558
- authToken,
13597
+ // password: options.password,
13598
+ // method: 'password',
13599
+ callbackURL: buildCallbackUrl({
13600
+ callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
13601
+ email: options.email,
13602
+ provider: 'email',
13603
+ isOpen,
13604
+ }),
13559
13605
  });
13560
13606
  logger.log('Email linked successfully');
13561
- if ('action' in result) {
13562
- setStatus({
13563
- status: 'awaiting-input',
13564
- });
13565
- client.auth.requestEmailVerification({
13566
- email: options.email,
13567
- redirectUrl: buildCallbackUrl({
13568
- email: options.email,
13569
- callbackUrl: (_a = options.emailVerificationRedirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.emailVerificationRedirectTo,
13570
- provider: 'email',
13571
- isOpen,
13572
- }),
13573
- });
13574
- updateUser();
13575
- setRequiresEmailVerification(true);
13576
- return onSuccess({
13577
- data: { requiresEmailVerification: true },
13578
- hookOptions,
13579
- options,
13580
- });
13581
- }
13582
- else {
13583
- return onSuccess({
13584
- data: {},
13585
- hookOptions,
13586
- options,
13587
- });
13588
- }
13607
+ return onSuccess({
13608
+ data: {},
13609
+ hookOptions,
13610
+ options,
13611
+ });
13589
13612
  }
13590
13613
  catch (e) {
13591
- const error = new OpenfortError('Failed to link email', OpenfortErrorType.AUTHENTICATION_ERROR, { error: e });
13614
+ const error = new OpenfortError('Failed to link email', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
13615
+ error: e,
13616
+ });
13592
13617
  setStatus({
13593
13618
  status: 'error',
13594
13619
  error: error,
@@ -13606,7 +13631,7 @@ const useEmailAuth = (hookOptions = {}) => {
13606
13631
  });
13607
13632
  try {
13608
13633
  if (!isValidEmail(options.email)) {
13609
- const error = new OpenfortError('Invalid email', OpenfortErrorType.VALIDATION_ERROR);
13634
+ const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
13610
13635
  setStatus({
13611
13636
  status: 'error',
13612
13637
  error,
@@ -13618,8 +13643,7 @@ const useEmailAuth = (hookOptions = {}) => {
13618
13643
  });
13619
13644
  }
13620
13645
  await client.auth.verifyEmail({
13621
- email: options.email,
13622
- state: options.state,
13646
+ token: options.state,
13623
13647
  });
13624
13648
  setStatus({
13625
13649
  status: 'success',
@@ -13633,7 +13657,9 @@ const useEmailAuth = (hookOptions = {}) => {
13633
13657
  });
13634
13658
  }
13635
13659
  catch (e) {
13636
- const error = new OpenfortError('Failed to verify email', OpenfortErrorType.AUTHENTICATION_ERROR, { error: e });
13660
+ const error = new OpenfortError('Failed to verify email', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
13661
+ error: e,
13662
+ });
13637
13663
  setStatus({
13638
13664
  status: 'error',
13639
13665
  error,
@@ -13749,6 +13775,7 @@ const EmailLogin = () => {
13749
13775
  setRoute(routes.EMAIL_VERIFICATION);
13750
13776
  }
13751
13777
  else {
13778
+ setEmail('');
13752
13779
  setRoute(routes.LOAD_WALLETS);
13753
13780
  }
13754
13781
  }
@@ -13779,92 +13806,604 @@ const EmailLogin = () => {
13779
13806
  }, children: "Forgot password?" }) })] }, loginError ? 'error' : 'no-error') }) }), jsx(Button, { onClick: handleSubmit, disabled: loginLoading, waiting: loginLoading, children: jsx(AnimatePresence, { initial: false, children: loginLoading ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: isRegister ? 'Signing up...' : 'Logging in...' }, "connectedText")) : isRegister ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: "Sign up" }, "connectedText")) : (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants$1, children: "Sign in" }, "connectedText")) }) })] }), jsxs(FooterContainer, { children: ["or", jsx("button", { type: "button", onClick: handleToggle, disabled: loginLoading, children: isRegister ? 'Sign in' : 'Sign up' })] })] }));
13780
13807
  };
13781
13808
 
13782
- const EmailVerification = () => {
13783
- const { client } = useOpenfortCore();
13784
- const { setRoute, emailInput: emailInStorage } = useOpenfort();
13785
- const [loading, setLoading] = useState(true);
13786
- const [verificationResponse, setVerificationResponse] = useState(null);
13787
- useEffect(() => {
13788
- const fixedUrl = window.location.href.replace('?state=', '&state='); // redirectUrl is not working with query params
13789
- const url = new URL(fixedUrl);
13790
- const openfortEmailVerificationUI = url.searchParams.get('openfortEmailVerificationUI');
13791
- if (!openfortEmailVerificationUI) {
13792
- // Send email verification flow
13793
- if (!emailInStorage) {
13794
- setRoute(routes.EMAIL_LOGIN);
13795
- return;
13809
+ const useEmailOtpAuth = (hookOptions = {}) => {
13810
+ const { client, updateUser } = useOpenfortCore();
13811
+ const [status, setStatus] = useState({
13812
+ status: 'idle',
13813
+ });
13814
+ const reset = useCallback(() => {
13815
+ setStatus({
13816
+ status: 'idle',
13817
+ });
13818
+ }, []);
13819
+ const { tryUseWallet } = useConnectToWalletPostAuth();
13820
+ const signInEmailOtp = useCallback(async (options) => {
13821
+ var _a, _b;
13822
+ try {
13823
+ setStatus({
13824
+ status: 'loading',
13825
+ });
13826
+ if (!options.email || !options.otp) {
13827
+ const error = new OpenfortError('Email and OTP are required', OpenfortReactErrorType.VALIDATION_ERROR);
13828
+ setStatus({
13829
+ status: 'error',
13830
+ error,
13831
+ });
13832
+ return onError({
13833
+ hookOptions,
13834
+ options,
13835
+ error,
13836
+ });
13796
13837
  }
13797
- setLoading(false);
13798
- return;
13799
- }
13800
- // Verify email flow
13801
- const state = url.searchParams.get('state');
13802
- const email = url.searchParams.get('email');
13803
- if (!state) {
13804
- logger.error('No state found in URL');
13805
- return;
13838
+ if (!isValidEmail(options.email)) {
13839
+ const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
13840
+ setStatus({
13841
+ status: 'error',
13842
+ error,
13843
+ });
13844
+ return onError({
13845
+ hookOptions,
13846
+ options,
13847
+ error,
13848
+ });
13849
+ }
13850
+ const result = await client.auth.logInWithEmailOtp({
13851
+ email: options.email,
13852
+ otp: options.otp,
13853
+ });
13854
+ const { wallet } = await tryUseWallet({
13855
+ logoutOnError: (_a = options.logoutOnError) !== null && _a !== void 0 ? _a : hookOptions.logoutOnError,
13856
+ recoverWalletAutomatically: (_b = options.recoverWalletAutomatically) !== null && _b !== void 0 ? _b : hookOptions.recoverWalletAutomatically,
13857
+ });
13858
+ setStatus({
13859
+ status: 'success',
13860
+ });
13861
+ const user = result.user;
13862
+ await updateUser();
13863
+ return onSuccess({
13864
+ data: { user, wallet },
13865
+ hookOptions,
13866
+ options,
13867
+ });
13806
13868
  }
13807
- const removeParams = () => {
13808
- ['state', 'openfortEmailVerificationUI', 'email', 'openfortAuthProvider'].forEach((key) => {
13809
- url.searchParams.delete(key);
13869
+ catch (e) {
13870
+ const error = new OpenfortError('Failed to login with email OTP', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
13871
+ error: e,
13872
+ });
13873
+ setStatus({
13874
+ status: 'error',
13875
+ error: error,
13876
+ });
13877
+ return onError({
13878
+ hookOptions,
13879
+ options,
13880
+ error: error,
13810
13881
  });
13811
- window.history.replaceState({}, document.title, url.toString());
13812
- };
13813
- if (!email) {
13814
- setRoute(routes.EMAIL_LOGIN);
13815
- return;
13816
13882
  }
13817
- logger.log('EmailVerification', state, email);
13818
- (async () => {
13819
- try {
13820
- await client.auth.verifyEmail({
13821
- email,
13822
- state,
13883
+ }, [client, setStatus, updateUser, hookOptions]);
13884
+ const requestEmailOtp = useCallback(async (options) => {
13885
+ try {
13886
+ setStatus({
13887
+ status: 'requesting',
13888
+ });
13889
+ if (!options.email) {
13890
+ const error = new OpenfortError('Email is required', OpenfortReactErrorType.VALIDATION_ERROR);
13891
+ setStatus({
13892
+ status: 'error',
13893
+ error,
13823
13894
  });
13824
- setVerificationResponse({
13825
- success: true,
13895
+ return onError({
13896
+ hookOptions,
13897
+ options,
13898
+ error,
13826
13899
  });
13827
13900
  }
13828
- catch (e) {
13829
- setVerificationResponse({
13830
- success: false,
13831
- error: 'There was an error verifying your email. Please try again.',
13901
+ if (!isValidEmail(options.email)) {
13902
+ const error = new OpenfortError('Invalid email', OpenfortReactErrorType.VALIDATION_ERROR);
13903
+ setStatus({
13904
+ status: 'error',
13905
+ error,
13906
+ });
13907
+ return onError({
13908
+ hookOptions,
13909
+ options,
13910
+ error,
13832
13911
  });
13833
- logger.log('Error verifying email', e);
13834
- }
13835
- finally {
13836
- removeParams();
13837
- setLoading(false);
13838
13912
  }
13839
- })();
13840
- }, []);
13841
- if (loading) {
13842
- return (jsx(PageContent, { children: jsx(Loader, { header: "Checking if account is verified" }) }));
13843
- }
13844
- return (jsxs(PageContent, { children: [jsx(FloatingGraphic, { height: "190px", logoCenter: {
13845
- logo: jsx(EmailIcon, {}),
13846
- }, logoTopLeft: {
13847
- logo: jsx(EmailIcon, {}),
13848
- }, logoBottomRight: {
13849
- logo: jsx(EmailIcon, {}),
13850
- }, logoTopRight: {
13851
- logo: jsx(EmailIcon, {}),
13852
- }, logoBottomLeft: {
13853
- logo: jsx(EmailIcon, {}),
13854
- } }), jsx(ModalContent, { children: verificationResponse ? (jsxs(Fragment, { children: [jsx(ModalH1, { "$small": true, children: verificationResponse.success ? 'Email verified' : 'Email verification failed' }), jsxs(ModalBody, { children: [verificationResponse.error ? verificationResponse.error : 'Your email has been verified.', jsx(Button, { onClick: () => {
13855
- setRoute(routes.EMAIL_LOGIN);
13856
- }, style: { marginTop: 12 }, children: "Continue" })] })] })) : (jsxs(Fragment, { children: [jsx(ModalH1, { "$small": true, children: "Email sent" }), jsxs(ModalBody, { style: { height: 40 }, children: ["Please check your email.", jsx("br", {}), emailInStorage] }), jsx(TextLinkButton, { style: { textDecoration: 'underline' }, onClick: () => {
13857
- setRoute(routes.EMAIL_LOGIN);
13858
- }, children: "Go back to login" })] })) })] }));
13859
- };
13860
-
13861
- // TODO: Localize
13862
- const ExportKey = () => {
13863
- const { exportPrivateKey } = useWallets();
13864
- const [exportedKey, setExportedKey] = useState(null);
13865
- const [exportError, setExportError] = useState(null);
13866
- const [showExportedKey, setShowExportedKey] = useState(false);
13867
- useEffect(() => {
13913
+ await client.auth.requestEmailOtp({
13914
+ email: options.email,
13915
+ });
13916
+ setStatus({
13917
+ status: 'success',
13918
+ });
13919
+ return onSuccess({
13920
+ data: {},
13921
+ hookOptions,
13922
+ options,
13923
+ });
13924
+ }
13925
+ catch (e) {
13926
+ const error = new OpenfortError('Failed to request email OTP', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
13927
+ error: e,
13928
+ });
13929
+ setStatus({
13930
+ status: 'error',
13931
+ error: error,
13932
+ });
13933
+ return onError({
13934
+ hookOptions,
13935
+ options,
13936
+ error: error,
13937
+ });
13938
+ }
13939
+ }, [client, setStatus, updateUser, hookOptions]);
13940
+ return {
13941
+ signInEmailOtp,
13942
+ requestEmailOtp,
13943
+ reset,
13944
+ isRequesting: status.status === 'requesting',
13945
+ ...mapStatus(status),
13946
+ isAwaitingInput: status.status === 'awaiting-input',
13947
+ };
13948
+ };
13949
+
13950
+ const caretBlink = keyframes `
13951
+ 0%, 70%, 100% { opacity: 1; }
13952
+ 20%, 50% { opacity: 0; }
13953
+ `;
13954
+ const OtpContainer = styled$1.div `
13955
+ display: flex;
13956
+ align-items: center;
13957
+ justify-content: center;
13958
+
13959
+ --border: ${({ showBorder }) => (showBorder ? 'var(--ck-body-color-muted)' : 'transparent')};
13960
+ `;
13961
+ const pulse = keyframes `
13962
+ 0% {
13963
+ opacity: 100%;
13964
+ }
13965
+ 50% {
13966
+ opacity: 40%;
13967
+ }
13968
+ 100% {
13969
+ opacity: 100%;
13970
+ }
13971
+ `;
13972
+ const dist = 2;
13973
+ const shakeKeyframes = keyframes `
13974
+ 0%{ transform:none; }
13975
+ 25%{ transform:translateX(${dist}px); }
13976
+ 50%{ transform:translateX(-${dist}px); }
13977
+ 75%{ transform:translateX(${dist}px); }
13978
+ 100%{ transform:none; }
13979
+ `;
13980
+ const keyframeSuccess = keyframes `
13981
+ 0% { transform: scale(1); }
13982
+ 50% { transform: scale(1.1); }
13983
+ 100% { transform: scale(1); }
13984
+ `;
13985
+ const OTPGroup = styled$1.div `
13986
+ display: flex;
13987
+
13988
+ outline-width: 3px;
13989
+ outline-style: solid;
13990
+ border-radius: 0.375rem;
13991
+ transition: outline-color 0.3s, border-radius .5s;
13992
+
13993
+ outline-color: ${({ isError, isSuccess }) => {
13994
+ if (isError)
13995
+ return 'var(--ck-body-color-danger)';
13996
+ if (isSuccess)
13997
+ return 'var(--ck-body-color-valid)';
13998
+ return 'transparent';
13999
+ }};
14000
+
14001
+ ${({ isLoading }) => isLoading &&
14002
+ css `
14003
+ animation: ${pulse} 1s ease-in-out infinite;
14004
+ `}
14005
+
14006
+ ${({ isError }) => isError &&
14007
+ css `
14008
+ animation: ${shakeKeyframes} 220ms ease-out both;
14009
+ `}
14010
+
14011
+ ${({ isSuccess }) => isSuccess &&
14012
+ css `
14013
+ border-radius: 3rem;
14014
+ min-width: 3.5rem;
14015
+ ${OTPSlotWrapper} {
14016
+ width: 0;
14017
+ border: 0;
14018
+ transition: width .5s, border .5s;
14019
+ }
14020
+ animation: ${keyframeSuccess} 220ms ease-out both;
14021
+ animation-delay: 250ms;
14022
+ `}
14023
+ `;
14024
+ const OTPSlotWrapper = styled$1.div `
14025
+ position: relative;
14026
+ width: 2.5rem;
14027
+ height: 3.5rem;
14028
+ font-size: 2rem;
14029
+
14030
+ display: flex;
14031
+ align-items: center;
14032
+ justify-content: center;
14033
+
14034
+ transition: all 0.3s;
14035
+
14036
+ border-top: 1px solid var(--border);
14037
+ border-bottom: 1px solid var(--border);
14038
+ border-right: 0.5px solid var(--border);
14039
+ border-left: 0.5px solid var(--border);
14040
+
14041
+ &:first-child {
14042
+ border-left: 1px solid var(--border);
14043
+ border-radius: 0.375rem 0 0 0.375rem;
14044
+ }
14045
+
14046
+ &:last-child {
14047
+ border-radius: 0 0.375rem 0.375rem 0;
14048
+ }
14049
+
14050
+ outline: ${({ isActive }) => (isActive ? '2px solid var(--ck-connectbutton-color)' : '0')};
14051
+ z-index: ${({ isActive }) => (isActive ? 1 : 0)};
14052
+ outline-offset: 0;
14053
+
14054
+ cursor: text;
14055
+ color: var(--ck-body-color);
14056
+ `;
14057
+ const OTPNumberValue = styled$1.div `
14058
+ opacity: ${({ $hide }) => ($hide ? 0 : 1)};
14059
+ transition: opacity 0.3s;
14060
+ `;
14061
+ const OTPHiddenInput = styled$1.input `
14062
+ position: absolute;
14063
+ inset: 0;
14064
+ opacity: 0;
14065
+ cursor: text;
14066
+ caret-color: transparent; /* Hide native caret */
14067
+ `;
14068
+ const FakeCaretWrapper = styled$1.div `
14069
+ position: absolute;
14070
+ inset: 0;
14071
+ pointer-events: none;
14072
+
14073
+ display: flex;
14074
+ align-items: center;
14075
+ justify-content: center;
14076
+
14077
+ animation: ${caretBlink} 1.2s ease-out infinite;
14078
+ `;
14079
+ const CaretBar = styled$1.div `
14080
+ width: 1px;
14081
+ height: 2rem;
14082
+ background: var(--ck-body-color);
14083
+ `;
14084
+ const keyframeWrapper = keyframes `
14085
+ 0% { transform: scale(0); }
14086
+ 100% { transform: scale(1); }
14087
+ `;
14088
+ const SuccessTickWrapper = styled$1.div `
14089
+ position: absolute;
14090
+ inset: 5px;
14091
+ display: flex;
14092
+ animation: ${keyframeWrapper} 200ms ease-out both;
14093
+ animation-delay: 200ms;
14094
+ color: var(--ck-body-color-valid);
14095
+ `;
14096
+
14097
+ function FakeCaret() {
14098
+ return (jsx(FakeCaretWrapper, { children: jsx(CaretBar, {}) }));
14099
+ }
14100
+ function OtpInputStandalone({ length = 6, onChange, onComplete, isLoading, isError, isSuccess, }) {
14101
+ const [values, setValues] = useState(Array(length).fill(''));
14102
+ const [activeIndex, setActiveIndex] = useState(0);
14103
+ const canEdit = !isLoading && !isError && !isSuccess;
14104
+ const inputsRef = useRef([]);
14105
+ const handleInput = (index, char) => {
14106
+ var _a;
14107
+ if (!char.match(/^[0-9]$/))
14108
+ return;
14109
+ if (!canEdit)
14110
+ return;
14111
+ const newValues = [...values];
14112
+ newValues[index] = char;
14113
+ setValues(newValues);
14114
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValues.join(''));
14115
+ // Move cursor to next box
14116
+ if (index < length - 1) {
14117
+ setActiveIndex(index + 1);
14118
+ (_a = inputsRef.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus();
14119
+ }
14120
+ };
14121
+ useEffect(() => {
14122
+ if (values.every((v) => v !== '')) {
14123
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(values.join(''));
14124
+ }
14125
+ }, [values]);
14126
+ const handleBackspace = (index) => {
14127
+ var _a;
14128
+ const newValues = [...values];
14129
+ if (newValues[index] === '') {
14130
+ if (index > 0) {
14131
+ // Move back
14132
+ setActiveIndex(index - 1);
14133
+ (_a = inputsRef.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
14134
+ }
14135
+ newValues[index - 1] = '';
14136
+ }
14137
+ else {
14138
+ newValues[index] = '';
14139
+ }
14140
+ setValues(newValues);
14141
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValues.join(''));
14142
+ };
14143
+ const handlePaste = (e) => {
14144
+ var _a;
14145
+ const pasted = e.clipboardData.getData('text').replace(/\D/g, '');
14146
+ if (!pasted)
14147
+ return;
14148
+ const arr = pasted.substring(0, length).split('');
14149
+ const newValues = [...values];
14150
+ arr.forEach((char, i) => {
14151
+ newValues[i] = char;
14152
+ });
14153
+ setValues(newValues);
14154
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValues.join(''));
14155
+ const finalIndex = Math.min(arr.length - 1, length - 1);
14156
+ setActiveIndex(finalIndex);
14157
+ (_a = inputsRef.current[finalIndex]) === null || _a === void 0 ? void 0 : _a.focus();
14158
+ };
14159
+ const handleFocus = (i) => {
14160
+ var _a, _b;
14161
+ if (activeIndex !== -1) {
14162
+ setActiveIndex(i);
14163
+ return;
14164
+ }
14165
+ const firstEmptyIndex = values.indexOf('');
14166
+ if (firstEmptyIndex !== -1) {
14167
+ setActiveIndex(firstEmptyIndex);
14168
+ (_a = inputsRef.current[firstEmptyIndex]) === null || _a === void 0 ? void 0 : _a.focus();
14169
+ }
14170
+ else {
14171
+ setActiveIndex(length - 1);
14172
+ (_b = inputsRef.current[length - 1]) === null || _b === void 0 ? void 0 : _b.focus();
14173
+ }
14174
+ };
14175
+ useEffect(() => {
14176
+ var _a;
14177
+ if (!isError) {
14178
+ setValues(Array(length).fill(''));
14179
+ setActiveIndex(0);
14180
+ (_a = inputsRef.current[0]) === null || _a === void 0 ? void 0 : _a.focus();
14181
+ }
14182
+ }, [isError]);
14183
+ return (jsx(OtpContainer, { showBorder: !isSuccess, children: jsxs(OTPGroup, { isError: isError, isSuccess: isSuccess, isLoading: isLoading, children: [values.slice(0, 6).map((value, idx) => {
14184
+ const index = idx;
14185
+ return (jsxs(OTPSlotWrapper, { isActive: canEdit && activeIndex === index, children: [jsx(OTPHiddenInput, { ref: (el) => {
14186
+ inputsRef.current[index] = el;
14187
+ }, value: "", inputMode: "numeric", onBlur: () => setActiveIndex(-1), autoComplete: "one-time-code", autoFocus: index === 0, onFocus: () => handleFocus(index), onPaste: handlePaste, onKeyDown: (e) => {
14188
+ if (!canEdit)
14189
+ return;
14190
+ if (e.key === 'Backspace') {
14191
+ e.preventDefault();
14192
+ handleBackspace(index);
14193
+ }
14194
+ }, onChange: (e) => handleInput(index, e.target.value) }), value && jsx(OTPNumberValue, { "$hide": isSuccess, children: value }), !value && activeIndex === index && jsx(FakeCaret, {})] }, index));
14195
+ }), isSuccess && (jsx(SuccessTickWrapper, { children: jsx(TickIcon, { width: '100%', height: '100%' }) }))] }) }));
14196
+ }
14197
+
14198
+ const Body$1 = styled.p `
14199
+ color: var(--ck-body-color);
14200
+ text-align: center;
14201
+ margin-bottom: 16px;
14202
+ `;
14203
+ const ResultContainer$1 = styled.div `
14204
+ margin-top: 16px;
14205
+ height: 24px;
14206
+ text-align: center;
14207
+ `;
14208
+ const FooterButtonText$1 = styled.button `
14209
+ background: none;
14210
+ border: none;
14211
+ cursor: pointer;
14212
+ padding: 0;
14213
+ color: var(--ck-body-color-muted);
14214
+ transition: color 0.3s;
14215
+
14216
+ &:disabled {
14217
+ color: var(--ck-body-color-muted) !important;
14218
+ cursor: not-allowed;
14219
+ }
14220
+ `;
14221
+ const FooterTextButton$1 = styled.p `
14222
+ color: var(--ck-body-color-muted);
14223
+ text-align: center;
14224
+ margin-top: 16px;
14225
+ &:hover {
14226
+ ${FooterButtonText$1} {
14227
+ color: var(--ck-body-color);
14228
+ }
14229
+ }
14230
+ `;
14231
+
14232
+ const RESEND_COOLDOWN_MS$1 = 10000;
14233
+ const SUCCESS_REDIRECT_DELAY_MS$1 = 2000;
14234
+ const ERROR_DISPLAY_DURATION_MS$1 = 2000;
14235
+ const EmailOTP = () => {
14236
+ const { emailInput: email, previousRoute, setRoute, setEmailInput } = useOpenfort();
14237
+ const { isLoading, requestEmailOtp, signInEmailOtp } = useEmailOtpAuth({
14238
+ recoverWalletAutomatically: false,
14239
+ });
14240
+ const onBack = useMemo(() => {
14241
+ if ((previousRoute === null || previousRoute === void 0 ? void 0 : previousRoute.route) === routes.EMAIL_VERIFICATION)
14242
+ return routes.PROVIDERS;
14243
+ return 'back';
14244
+ }, [previousRoute]);
14245
+ const [canSendOtp, setCanSendOtp] = useState(true);
14246
+ const [status, setStatus] = useState('idle');
14247
+ // Single ref to track if initial OTP request has been made
14248
+ const hasRequestedInitialOtpRef = useRef(false);
14249
+ // Memoize the OTP request function to prevent unnecessary recreations
14250
+ const sendOtpRequest = useCallback(async () => {
14251
+ const { error } = await requestEmailOtp({ email });
14252
+ if (error) {
14253
+ logger.error('Error requesting email OTP:', error);
14254
+ setStatus('error');
14255
+ }
14256
+ else {
14257
+ setStatus('idle');
14258
+ }
14259
+ }, [email, requestEmailOtp]);
14260
+ // Initial OTP request on mount
14261
+ useEffect(() => {
14262
+ if (hasRequestedInitialOtpRef.current)
14263
+ return;
14264
+ hasRequestedInitialOtpRef.current = true;
14265
+ sendOtpRequest();
14266
+ }, [sendOtpRequest]);
14267
+ // Handle OTP completion
14268
+ const handleComplete = useCallback(async (otp) => {
14269
+ logger.log('OTP entered:', otp);
14270
+ setStatus('loading');
14271
+ const { error } = await signInEmailOtp({ email, otp });
14272
+ if (error) {
14273
+ logger.error('Error logging in with email OTP:', error);
14274
+ setStatus('error');
14275
+ }
14276
+ else {
14277
+ setStatus('success');
14278
+ }
14279
+ }, [email, signInEmailOtp]);
14280
+ // Handle status changes and side effects
14281
+ useEffect(() => {
14282
+ let timeoutId;
14283
+ switch (status) {
14284
+ case 'send-otp':
14285
+ setStatus('sending-otp');
14286
+ sendOtpRequest();
14287
+ break;
14288
+ case 'success':
14289
+ timeoutId = setTimeout(() => {
14290
+ setEmailInput('');
14291
+ setRoute(routes.LOAD_WALLETS);
14292
+ }, SUCCESS_REDIRECT_DELAY_MS$1);
14293
+ break;
14294
+ case 'error':
14295
+ timeoutId = setTimeout(() => {
14296
+ setStatus('idle');
14297
+ }, ERROR_DISPLAY_DURATION_MS$1);
14298
+ break;
14299
+ }
14300
+ return () => {
14301
+ if (timeoutId)
14302
+ clearTimeout(timeoutId);
14303
+ };
14304
+ }, [status, sendOtpRequest, setEmailInput, setRoute]);
14305
+ // Handle resend cooldown
14306
+ useEffect(() => {
14307
+ if (canSendOtp)
14308
+ return;
14309
+ const timerId = setTimeout(() => {
14310
+ setCanSendOtp(true);
14311
+ }, RESEND_COOLDOWN_MS$1);
14312
+ return () => clearTimeout(timerId);
14313
+ }, [canSendOtp]);
14314
+ // Memoize button text to avoid recalculation
14315
+ const sendButtonText = useMemo(() => {
14316
+ if (!canSendOtp)
14317
+ return 'Code Sent!';
14318
+ if (status === 'sending-otp')
14319
+ return 'Sending...';
14320
+ return 'Resend Code';
14321
+ }, [canSendOtp, status]);
14322
+ const handleResendClick = useCallback(() => {
14323
+ setStatus('send-otp');
14324
+ setCanSendOtp(false);
14325
+ }, []);
14326
+ const isResendDisabled = !canSendOtp || status === 'sending-otp' || status === 'send-otp';
14327
+ return (jsxs(PageContent, { onBack: onBack, children: [jsx(ModalHeading, { children: "Enter your code" }), jsx(FloatingGraphic, { height: "100px", marginTop: "8px", marginBottom: "10px", logoCenter: {
14328
+ logo: jsx(EmailIcon, {}),
14329
+ } }), jsxs(ModalBody, { children: [jsxs(Body$1, { children: ["Please check ", jsx("b", { children: email }), " for an email from openfort.io and enter your code below."] }), jsx(OtpInputStandalone, { onComplete: handleComplete, isLoading: status === 'loading' || isLoading, isError: status === 'error', isSuccess: status === 'success' }), jsxs(ResultContainer$1, { children: [status === 'success' && jsx(ModalBody, { "$valid": true, children: "Code verified successfully!" }), status === 'error' && jsx(ModalBody, { "$error": true, children: "Invalid code. Please try again." })] }), jsxs(FooterTextButton$1, { children: ["Didn't receive the code?", ' ', jsx(FooterButtonText$1, { type: "button", onClick: handleResendClick, disabled: isResendDisabled, children: sendButtonText })] })] }), jsx(PoweredByFooter, {})] }));
14330
+ };
14331
+
14332
+ const EmailVerification = () => {
14333
+ const { setRoute, emailInput, setEmailInput } = useOpenfort();
14334
+ const [loading, setLoading] = useState(true);
14335
+ const [verificationResponse, setVerificationResponse] = useState(null);
14336
+ const isVerifying = useRef(false);
14337
+ useEffect(() => {
14338
+ if (isVerifying.current)
14339
+ return;
14340
+ isVerifying.current = true;
14341
+ const url = new URL(window.location.href);
14342
+ if (emailInput) {
14343
+ // Not callback flow
14344
+ setLoading(false);
14345
+ return;
14346
+ }
14347
+ // Verify email flow
14348
+ const email = url.searchParams.get('email');
14349
+ const removeParams = () => {
14350
+ ['state', 'openfortEmailVerificationUI', 'email', 'openfortAuthProvider'].forEach((key) => {
14351
+ url.searchParams.delete(key);
14352
+ });
14353
+ window.history.replaceState({}, document.title, url.toString());
14354
+ };
14355
+ logger.log('Email verification', email);
14356
+ if (!email) {
14357
+ setRoute(routes.EMAIL_LOGIN);
14358
+ return;
14359
+ }
14360
+ try {
14361
+ // ASSUMING IT WORKS
14362
+ // TODO: TMP FIX
14363
+ setEmailInput(email);
14364
+ setVerificationResponse({
14365
+ success: true,
14366
+ });
14367
+ }
14368
+ catch (e) {
14369
+ setVerificationResponse({
14370
+ success: false,
14371
+ error: 'There was an error verifying your email. Please try again.',
14372
+ });
14373
+ logger.log('Error verifying email', e);
14374
+ }
14375
+ finally {
14376
+ removeParams();
14377
+ setLoading(false);
14378
+ }
14379
+ }, []);
14380
+ if (loading) {
14381
+ return (jsx(PageContent, { children: jsx(Loader, { header: "Checking if account is verified" }) }));
14382
+ }
14383
+ return (jsxs(PageContent, { children: [jsx(FloatingGraphic, { height: "190px", logoCenter: {
14384
+ logo: jsx(EmailIcon, {}),
14385
+ }, logoTopLeft: {
14386
+ logo: jsx(EmailIcon, {}),
14387
+ }, logoBottomRight: {
14388
+ logo: jsx(EmailIcon, {}),
14389
+ }, logoTopRight: {
14390
+ logo: jsx(EmailIcon, {}),
14391
+ }, logoBottomLeft: {
14392
+ logo: jsx(EmailIcon, {}),
14393
+ } }), jsx(ModalContent, { children: verificationResponse ? (jsxs(Fragment, { children: [jsx(ModalH1, { "$small": true, children: verificationResponse.success ? 'Email verified' : 'Email verification failed' }), jsxs(ModalBody, { children: [verificationResponse.error ? verificationResponse.error : 'Your email has been verified.', jsx(Button, { onClick: () => {
14394
+ setRoute(routes.EMAIL_LOGIN);
14395
+ }, style: { marginTop: 12 }, children: "Continue" })] })] })) : (jsxs(Fragment, { children: [jsx(ModalH1, { "$small": true, children: "Email sent" }), jsxs(ModalBody, { style: { height: 40 }, children: ["Please check your email.", jsx("br", {}), emailInput] }), jsx(TextLinkButton, { style: { textDecoration: 'underline' }, onClick: () => {
14396
+ setRoute(routes.EMAIL_LOGIN);
14397
+ }, children: "Go back to login" })] })) })] }));
14398
+ };
14399
+
14400
+ // TODO: Localize
14401
+ const ExportKey = () => {
14402
+ const { exportPrivateKey } = useWallets();
14403
+ const [exportedKey, setExportedKey] = useState(null);
14404
+ const [exportError, setExportError] = useState(null);
14405
+ const [showExportedKey, setShowExportedKey] = useState(false);
14406
+ useEffect(() => {
13868
14407
  const asyncExportKey = async () => {
13869
14408
  try {
13870
14409
  const key = await exportPrivateKey();
@@ -13955,42 +14494,41 @@ const ResetPassword = () => {
13955
14494
  const fixedUrl = window.location.href.replace('?state=', '&state='); // redirectUrl is not working with query params
13956
14495
  const url = new URL(fixedUrl);
13957
14496
  const [password, setPassword] = React.useState('');
13958
- const { setRoute, triggerResize } = useOpenfort();
13959
- const { client, updateUser } = useOpenfortCore();
13960
- const [loading, setLoading] = React.useState(false);
14497
+ // const { setRoute, triggerResize } = useOpenfort()
14498
+ // const { client, updateUser } = useOpenfortCore()
14499
+ const [loading, _setLoading] = React.useState(false);
13961
14500
  const email = url.searchParams.get('email');
14501
+ // OTP_TODO: Reset password
13962
14502
  const handleSubmit = async () => {
13963
- setLoading(true);
13964
- const state = url.searchParams.get('state');
13965
- if (!email || !state) {
13966
- logger.log('No email or state found');
13967
- setLoading(false);
13968
- return;
13969
- }
13970
- try {
13971
- await client.auth.resetPassword({
13972
- password: password,
13973
- email,
13974
- state,
13975
- });
13976
- await client.auth.logInWithEmailPassword({
13977
- email,
13978
- password,
13979
- });
13980
- const user = await updateUser();
13981
- if (!user)
13982
- throw new Error('No user found');
13983
- ['openfortForgotPasswordUI', 'state', 'email'].forEach((param) => {
13984
- url.searchParams.delete(param);
13985
- });
13986
- window.history.replaceState({}, document.title, url.toString());
13987
- setRoute(routes.LOAD_WALLETS);
13988
- }
13989
- catch (e) {
13990
- logger.log('Reset password error', e);
13991
- setLoading(false);
13992
- triggerResize();
13993
- }
14503
+ // setLoading(true)
14504
+ // const state = url.searchParams.get('state')
14505
+ // if (!email || !state) {
14506
+ // logger.log('No email or state found')
14507
+ // setLoading(false)
14508
+ // return
14509
+ // }
14510
+ // try {
14511
+ // await client.auth.resetPassword({
14512
+ // password: password,
14513
+ // email,
14514
+ // state,
14515
+ // })
14516
+ // await client.auth.logInWithEmailPassword({
14517
+ // email,
14518
+ // password,
14519
+ // })
14520
+ // const user = await updateUser()
14521
+ // if (!user) throw new Error('No user found')
14522
+ // ;['openfortForgotPasswordUI', 'state', 'email'].forEach((param) => {
14523
+ // url.searchParams.delete(param)
14524
+ // })
14525
+ // window.history.replaceState({}, document.title, url.toString())
14526
+ // setRoute(routes.LOAD_WALLETS)
14527
+ // } catch (e) {
14528
+ // logger.log('Reset password error', e)
14529
+ // setLoading(false)
14530
+ // triggerResize()
14531
+ // }
13994
14532
  };
13995
14533
  return (jsx(PageContent, { children: jsxs("form", { onSubmit: (e) => {
13996
14534
  e.preventDefault();
@@ -14028,27 +14566,19 @@ const textVariants = {
14028
14566
  },
14029
14567
  };
14030
14568
  const LinkEmail = () => {
14031
- const [password, setPassword] = React.useState('');
14569
+ // const [password, setPassword] = React.useState('')
14032
14570
  const { setRoute, triggerResize, emailInput: email, setEmailInput: setEmail } = useOpenfort();
14033
14571
  const { client, updateUser } = useOpenfortCore();
14034
14572
  const [loginLoading, setLoginLoading] = React.useState(false);
14035
14573
  const [loginError, setLoginError] = React.useState(false);
14574
+ const { linkEmail } = useEmailAuth();
14036
14575
  const handleSubmit = async () => {
14037
14576
  setLoginLoading(true);
14038
14577
  await client.validateAndRefreshToken();
14039
- const authToken = await client.getAccessToken();
14040
- if (!authToken) {
14041
- logger.log('No token found');
14042
- setLoginLoading(false);
14043
- setLoginError('No token found.');
14044
- triggerResize();
14045
- return;
14046
- }
14047
14578
  try {
14048
- await client.auth.linkEmailPassword({
14579
+ await linkEmail({
14049
14580
  email,
14050
- password,
14051
- authToken,
14581
+ // emailVerificationRedirectTo: window.location.origin,
14052
14582
  });
14053
14583
  await updateUser();
14054
14584
  setEmail('');
@@ -14069,27 +14599,221 @@ const LinkEmail = () => {
14069
14599
  return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Link your email" }), jsxs("form", { onSubmit: (e) => {
14070
14600
  e.preventDefault();
14071
14601
  handleSubmit();
14072
- }, children: [jsx(Input, { style: { marginTop: 0 }, value: email, onChange: (e) => setEmail(e.target.value), type: "email", placeholder: "Enter your email", disabled: loginLoading }), jsx(Input, { value: password, onChange: (e) => setPassword(e.target.value), type: "password", placeholder: "Enter your password", disabled: loginLoading }), loginError && (jsx(ModalBody, { style: { height: 24, marginTop: 12 }, "$error": true, children: jsx(FitText, { children: loginError }) })), jsx(Button, { onClick: handleSubmit, disabled: loginLoading, waiting: loginLoading, children: jsx(AnimatePresence, { initial: false, children: loginLoading ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants, children: "Linking email..." }, "connectedText")) : (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants, children: "Link email" }, "connectedText")) }) })] })] }));
14602
+ }, children: [jsx(Input, { style: { marginTop: 0 }, value: email, onChange: (e) => setEmail(e.target.value), type: "email", placeholder: "Enter your email", disabled: loginLoading }), loginError && (jsx(ModalBody, { style: { height: 24, marginTop: 12 }, "$error": true, children: jsx(FitText, { children: loginError }) })), jsx(Button, { onClick: handleSubmit, disabled: loginLoading, waiting: loginLoading, children: jsx(AnimatePresence, { initial: false, children: loginLoading ? (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants, children: "Linking email..." }, "connectedText")) : (jsx(TextContainer, { initial: 'initial', animate: 'animate', exit: 'exit', variants: textVariants, children: "Link email" }, "connectedText")) }) })] })] }));
14603
+ };
14604
+
14605
+ const getProviderName = (provider) => {
14606
+ switch (provider) {
14607
+ case 'wallet':
14608
+ case 'siwe':
14609
+ return 'Wallet';
14610
+ case 'email':
14611
+ case 'credential':
14612
+ return 'Email';
14613
+ default:
14614
+ return provider.charAt(0).toUpperCase() + provider.slice(1);
14615
+ }
14616
+ };
14617
+
14618
+ const ProviderIconWrapper$2 = styled.div `
14619
+ width: 24px;
14620
+ height: 24px;
14621
+ flex-shrink: 0;
14622
+ display: flex;
14623
+ align-items: center;
14624
+ justify-content: center;
14625
+ `;
14626
+ const LinkedProviderButtonContainer = styled.div `
14627
+ ${ButtonContainer} {
14628
+ font-weight: var(--ck-primary-button-font-weight, 500);
14629
+ }
14630
+
14631
+ &:first-of-type {
14632
+ ${ButtonContainer}, ${ProviderInputInner} {
14633
+ margin-top: 0;
14634
+ }
14635
+ }
14636
+
14637
+ ${ButtonContainerInner} {
14638
+ padding: 0 20px;
14639
+ }
14640
+
14641
+ ${InnerContainer} {
14642
+ width: 100%;
14643
+ max-width: 100%;
14644
+ }
14645
+ `;
14646
+ const LinkedProviderButtonWrapper = styled.div `
14647
+ display: flex;
14648
+ align-items: center;
14649
+ gap: 12px;
14650
+ `;
14651
+ const LinkedProvidersGroupWrapper = styled.div `
14652
+ `;
14653
+ const LinkedProviderText = styled.div `
14654
+ flex: 1;
14655
+ overflow: hidden;
14656
+ text-overflow: ellipsis;
14657
+ white-space: nowrap;
14658
+ color: var(--ck-body-color-muted);
14659
+ text-align: start;
14660
+ max-width: 210px;
14661
+ `;
14662
+
14663
+ const WalletDisplay = ({ walletAddress }) => {
14664
+ var _a, _b;
14665
+ const ensFallbackConfig = useEnsFallbackConfig();
14666
+ const { data: ensName } = useEnsName({
14667
+ chainId: 1,
14668
+ address: walletAddress,
14669
+ config: ensFallbackConfig,
14670
+ });
14671
+ const context = useOpenfort();
14672
+ const themeContext = useThemeContext();
14673
+ const separator = ['web95', 'rounded', 'minimal'].includes((_b = (_a = themeContext.theme) !== null && _a !== void 0 ? _a : context.uiConfig.theme) !== null && _b !== void 0 ? _b : '')
14674
+ ? '....'
14675
+ : undefined;
14676
+ return ensName !== null && ensName !== void 0 ? ensName : truncateEthAddress(walletAddress, separator);
14677
+ };
14678
+ const ProviderHeader = ({ provider }) => {
14679
+ var _a;
14680
+ const { user } = useUser();
14681
+ switch (provider.provider) {
14682
+ case 'wallet':
14683
+ case 'siwe':
14684
+ return (jsx(LinkedProviderText, { children: jsx(WalletDisplay, { walletAddress: provider.accountId }) }));
14685
+ case 'phone':
14686
+ return jsx(LinkedProviderText, { children: provider.accountId });
14687
+ default:
14688
+ return (jsx(LinkedProviderText, { style: { textTransform: (user === null || user === void 0 ? void 0 : user.email) ? 'none' : 'capitalize' }, children: (_a = user === null || user === void 0 ? void 0 : user.email) !== null && _a !== void 0 ? _a : provider.provider }));
14689
+ }
14690
+ };
14691
+
14692
+ const WalletIconWrapper = ({ provider }) => {
14693
+ var _a;
14694
+ const wallets = useWagmiWallets();
14695
+ const wallet = useMemo(() => {
14696
+ return wallets.find((w) => { var _a; return ((_a = w.id) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === provider.walletClientType; });
14697
+ }, [provider]);
14698
+ if (provider.walletClientType === 'walletconnect')
14699
+ return jsx(Logos.WalletConnect, {});
14700
+ if (wallet)
14701
+ return jsx(Fragment, { children: (_a = wallet.iconConnector) !== null && _a !== void 0 ? _a : wallet.icon });
14702
+ return jsx(WalletIcon$1, {});
14703
+ };
14704
+ const ProviderIcon = ({ provider }) => {
14705
+ switch (provider.provider) {
14706
+ case 'email':
14707
+ case 'credential':
14708
+ return jsx(EmailIcon, {});
14709
+ // OTP_TODO: Wallet icon
14710
+ case 'wallet':
14711
+ case 'siwe':
14712
+ return jsx(WalletIconWrapper, { provider: provider });
14713
+ case 'phone':
14714
+ return jsx(PhoneIcon, {});
14715
+ case 'google':
14716
+ case 'twitter':
14717
+ case 'facebook':
14718
+ return providersLogos[provider.provider];
14719
+ default:
14720
+ return jsx(FitText, { children: provider.provider.substring(0, 4).toUpperCase() });
14721
+ }
14722
+ };
14723
+
14724
+ const ProviderIconContainer$1 = styled.div `
14725
+ width: 100%;
14726
+ display: flex;
14727
+ align-items: center;
14728
+ justify-content: center;
14729
+ `;
14730
+ const ProviderIconWrapper$1 = styled.div `
14731
+ width: 54px;
14732
+ height: 54px;
14733
+ flex-shrink: 0;
14734
+ display: flex;
14735
+ align-items: center;
14736
+ justify-content: center;
14737
+ background-color: var(--ck-body-background-secondary);
14738
+ border-radius: 28px;
14739
+ `;
14740
+ const ProviderIconInner$1 = styled.div `
14741
+ width: 32px;
14742
+ height: 32px;
14743
+ flex-shrink: 0;
14744
+ display: flex;
14745
+ align-items: center;
14746
+ justify-content: center;
14747
+ `;
14748
+ const SiweContent = ({ provider }) => {
14749
+ var _a, _b;
14750
+ const address = provider.accountId;
14751
+ const ensFallbackConfig = useEnsFallbackConfig();
14752
+ const { data: ensName } = useEnsName({
14753
+ chainId: 1,
14754
+ address,
14755
+ config: ensFallbackConfig,
14756
+ });
14757
+ const context = useOpenfort();
14758
+ const themeContext = useThemeContext();
14759
+ const separator = ['web95', 'rounded', 'minimal'].includes((_b = (_a = themeContext.theme) !== null && _a !== void 0 ? _a : context.uiConfig.theme) !== null && _b !== void 0 ? _b : '')
14760
+ ? '....'
14761
+ : undefined;
14762
+ return (jsxs(Fragment, { children: [jsx(ModalH1, { children: jsx(CopyText, { value: address, children: ensName !== null && ensName !== void 0 ? ensName : truncateEthAddress(address, separator) }) }), jsxs("div", { style: { marginTop: '16px' }, children: ["Linked via Sign-In with Ethereum (SIWE)", jsx(Button, { onClick: () => context.setRoute({ route: 'removeLinkedProvider', provider }), children: "Remove this wallet" })] })] }));
14763
+ };
14764
+ const OAuthContent = ({ provider }) => {
14765
+ const { user } = useUser();
14766
+ const { setRoute } = useOpenfort();
14767
+ return (jsxs(Fragment, { children: [jsx(ModalH1, { children: provider.provider.charAt(0).toUpperCase() + provider.provider.slice(1) }), jsxs("div", { style: { marginTop: '16px' }, children: [user === null || user === void 0 ? void 0 : user.email, jsxs(Button, { onClick: () => setRoute({ route: 'removeLinkedProvider', provider }), children: ["Remove ", provider.provider] })] })] }));
14768
+ };
14769
+ const LinkedProvider$1 = () => {
14770
+ const { route } = useOpenfort();
14771
+ const provider = useMemo(() => {
14772
+ if (route.route === 'linkedProvider') {
14773
+ return route.provider;
14774
+ }
14775
+ throw new Error('No provider found in route');
14776
+ }, []);
14777
+ const getProviderDetails = (provider) => {
14778
+ switch (provider.provider) {
14779
+ case 'siwe':
14780
+ return jsx(SiweContent, { provider: provider });
14781
+ case 'google':
14782
+ case 'facebook':
14783
+ case 'twitter':
14784
+ return jsx(OAuthContent, { provider: provider });
14785
+ default:
14786
+ return (jsxs("div", { style: { marginTop: '16px', display: 'flex', alignItems: 'center', gap: '8px', flexDirection: 'column' }, children: [jsxs("div", { children: ["Authentication method: ", jsx("b", { children: getProviderName(provider.provider) })] }), jsx(FitText, { children: jsx(ProviderHeader, { provider: provider }) })] }));
14787
+ }
14788
+ };
14789
+ return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: getProviderName(provider.provider) }), jsxs(ModalContent, { style: { paddingBottom: 0 }, children: [jsx(ProviderIconContainer$1, { children: jsx(ProviderIconWrapper$1, { children: jsx(ProviderIconInner$1, { children: jsx(ProviderIcon, { provider: provider }) }) }) }), jsx(ModalBody, { children: getProviderDetails(provider) })] })] }));
14073
14790
  };
14074
14791
 
14075
14792
  function useProviders() {
14076
- const { user } = useOpenfortCore();
14793
+ const { user, linkedAccounts } = useOpenfortCore();
14077
14794
  const { uiConfig: options, thirdPartyAuth, setOpen } = useOpenfort();
14078
14795
  const allProviders = (options === null || options === void 0 ? void 0 : options.authProviders) || [];
14079
14796
  const providers = allProviders.filter((p) => p !== UIAuthProvider.GUEST) || [];
14080
- const linkedProviders = user ? providers.filter((p) => { var _a; return (_a = user.linkedAccounts) === null || _a === void 0 ? void 0 : _a.find((a) => a.provider === p); }) : [];
14797
+ const linkedProviders = user ? providers.filter((p) => linkedAccounts === null || linkedAccounts === void 0 ? void 0 : linkedAccounts.find((a) => a.provider === p)) : [];
14081
14798
  const availableProviders = user
14082
14799
  ? providers.filter((provider) => {
14083
- var _a;
14084
14800
  if (provider === UIAuthProvider.WALLET)
14085
14801
  return true; // Wallet is always available
14086
- return !((_a = user.linkedAccounts) === null || _a === void 0 ? void 0 : _a.find((a) => a.provider === provider));
14802
+ if (user.email && (provider === UIAuthProvider.EMAIL_PASSWORD || provider === UIAuthProvider.EMAIL_OTP)) {
14803
+ return false; // If user has email, don't show email password or otp
14804
+ }
14805
+ if (provider === UIAuthProvider.EMAIL_PASSWORD)
14806
+ return false; // Disable email password linking for now
14807
+ if (user.phoneNumber && provider === UIAuthProvider.PHONE) {
14808
+ return false; // If user has phone number, don't show phone otp
14809
+ }
14810
+ return !(linkedAccounts === null || linkedAccounts === void 0 ? void 0 : linkedAccounts.find((a) => a.provider === provider));
14087
14811
  })
14088
14812
  : providers;
14089
14813
  useEffect(() => {
14090
14814
  if (thirdPartyAuth) {
14091
14815
  setOpen(false);
14092
- logger.error(new OpenfortError('When using external third party auth providers, openfort Auth providers are not available. Either remove the `thirdPartyAuth` or authenticate your users using Auth hooks.', OpenfortErrorType.CONFIGURATION_ERROR));
14816
+ logger.error(new OpenfortError('When using external third party auth providers, openfort Auth providers are not available. Either remove the `thirdPartyAuth` or authenticate your users using Auth hooks.', OpenfortReactErrorType.CONFIGURATION_ERROR));
14093
14817
  }
14094
14818
  }, [thirdPartyAuth, setOpen]);
14095
14819
  const maxProviders = (options === null || options === void 0 ? void 0 : options.authProvidersLength) || 4;
@@ -14099,10 +14823,17 @@ function useProviders() {
14099
14823
  return { mainProviders: activeProviders, hasExcessProviders: false, remainingSocialProviders: [] };
14100
14824
  }
14101
14825
  // Separate social and non-social providers
14102
- const nonSocial = activeProviders.filter((p) => !socialProviders.includes(p));
14826
+ const nonSocial = activeProviders.filter((p, _, array) => {
14827
+ if (p === UIAuthProvider.EMAIL_OTP && array.includes(UIAuthProvider.EMAIL_PASSWORD)) {
14828
+ // If both email otp and email password are present, treat email otp as social to avoid showing both
14829
+ return false;
14830
+ }
14831
+ return !socialProviders.includes(p);
14832
+ });
14103
14833
  const social = activeProviders.filter((p) => socialProviders.includes(p));
14104
14834
  // Allow as many non-socials as possible, then fill the rest with socials
14105
14835
  const remainingSlots = maxProviders - nonSocial.length;
14836
+ const remainingSocialProviders = social.slice(Math.max(0, remainingSlots - 1));
14106
14837
  return {
14107
14838
  mainProviders: [...nonSocial, ...social.slice(0, Math.max(0, remainingSlots - 1))].sort((a, b) => {
14108
14839
  // sort them in the original order
@@ -14111,7 +14842,7 @@ function useProviders() {
14111
14842
  return indexA - indexB;
14112
14843
  }),
14113
14844
  hasExcessProviders: social.length > remainingSlots - 1,
14114
- remainingSocialProviders: social.slice(remainingSlots - 1),
14845
+ remainingSocialProviders,
14115
14846
  };
14116
14847
  }, [user, availableProviders, allProviders, maxProviders]);
14117
14848
  return {
@@ -14124,66 +14855,9 @@ function useProviders() {
14124
14855
  };
14125
14856
  }
14126
14857
 
14127
- const ProviderIconWrapper = styled.div `
14128
- width: 24px;
14129
- height: 24px;
14130
- flex-shrink: 0;
14131
- display: flex;
14132
- align-items: center;
14133
- justify-content: center;
14134
- `;
14135
- const LinkedProviderContainer = styled.div `
14136
- background-color: var(--ck-body-background-secondary);
14137
- border: var(--ck-body-divider) 1px solid;
14138
- display: flex;
14139
- align-items: center;
14140
- gap: 12px;
14141
- padding: 12px 16px;
14142
- border-radius: var(--ck-primary-button-border-radius);
14143
- overflow: hidden;
14144
- text-overflow: ellipsis;
14145
- `;
14146
- const LinkedProvidersGroupWrapper = styled.div `
14147
- display: flex;
14148
- flex-direction: column;
14149
- gap: 12px;
14150
- `;
14151
- const LinkedProviderText = styled.div `
14152
- flex: 1;
14153
- overflow: hidden;
14154
- text-overflow: ellipsis;
14155
- white-space: nowrap;
14156
- color: var(--ck-body-color-muted);
14157
- `;
14158
-
14159
- const WalletIcon$1 = ({ provider }) => {
14160
- var _a;
14161
- const wallets = useWagmiWallets();
14162
- const wallet = useMemo(() => {
14163
- return wallets.find((w) => { var _a; return ((_a = w.id) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === provider.walletClientType; });
14164
- }, [provider]);
14165
- if (provider.walletClientType === 'walletconnect')
14166
- return jsx(Logos.WalletConnect, {});
14167
- if (wallet)
14168
- return jsx(Fragment, { children: (_a = wallet.iconConnector) !== null && _a !== void 0 ? _a : wallet.icon });
14169
- return jsx(WalletIcon$2, {});
14170
- };
14171
- const ProviderIcon = ({ provider }) => {
14172
- switch (provider.provider) {
14173
- case 'email':
14174
- return jsx(EmailIcon, {});
14175
- case 'wallet':
14176
- return jsx(WalletIcon$1, { provider: provider });
14177
- case 'google':
14178
- case 'twitter':
14179
- case 'facebook':
14180
- return providersLogos[provider.provider];
14181
- default:
14182
- return jsx(FitText, { children: provider.provider.substring(0, 4).toUpperCase() });
14183
- }
14184
- };
14185
14858
  const LinkedProvider = ({ provider }) => {
14186
- return (jsxs(LinkedProviderContainer, { children: [jsx(ProviderIconWrapper, { children: jsx(ProviderIcon, { provider: provider }) }), jsx(LinkedProviderText, { children: provider.address || provider.email || 'unknown' })] }));
14859
+ const { setRoute } = useOpenfort();
14860
+ return (jsx(LinkedProviderButtonContainer, { children: jsx(Button, { onClick: () => setRoute({ route: routes.LINKED_PROVIDER, provider }), fitText: false, children: jsxs(LinkedProviderButtonWrapper, { children: [jsx(ProviderIconWrapper$2, { children: jsx(ProviderIcon, { provider: provider }) }), jsx(ProviderHeader, { provider: provider })] }) }) }));
14187
14861
  };
14188
14862
  const AddLinkedProviderButton = () => {
14189
14863
  const { setRoute } = useOpenfort();
@@ -14191,7 +14865,12 @@ const AddLinkedProviderButton = () => {
14191
14865
  return (jsx(Button, { disabled: unlinkedProviders.length === 0, onClick: () => setRoute(routes.PROVIDERS), children: "+" }));
14192
14866
  };
14193
14867
  const LinkedProvidersGroup = () => {
14194
- const { user, isLoading } = useOpenfortCore();
14868
+ const { linkedAccounts, user, isLoading } = useOpenfortCore();
14869
+ const { triggerResize } = useOpenfort();
14870
+ useEffect(() => {
14871
+ if (!isLoading)
14872
+ triggerResize();
14873
+ }, [isLoading]);
14195
14874
  // TODO: Show loading
14196
14875
  if (isLoading) {
14197
14876
  return (jsx("div", { children: jsx(AddLinkedProviderButton, {}) }));
@@ -14200,13 +14879,13 @@ const LinkedProvidersGroup = () => {
14200
14879
  if (!user) {
14201
14880
  return (jsx("div", { children: jsx(AddLinkedProviderButton, {}) }));
14202
14881
  }
14203
- if (user.linkedAccounts.length === 0) {
14204
- return (jsx("div", { children: jsx(AddLinkedProviderButton, {}) }));
14205
- }
14206
- return (jsxs(Fragment, { children: [jsx(LinkedProvidersGroupWrapper, { children: user.linkedAccounts.map((provider) => (jsx(LinkedProvider, { provider: provider }, `${provider.provider}-${provider.address || provider.email || 'unknown'}`))) }), jsx(AddLinkedProviderButton, {})] }));
14882
+ return (jsxs(Fragment, { children: [jsxs(LinkedProvidersGroupWrapper, { children: [linkedAccounts.length === 0 && !user.email && !user.phoneNumber && (jsxs(ModalContent, { children: ["You are logged in as a guest.", jsx(ModalBody, { children: "Add authentication methods to avoid losing access to your account." })] })), !linkedAccounts.find((a) => a.provider === 'credential') && user.email && (jsx(LinkedProvider, { provider: { provider: 'credential', accountId: user.email } }, `credential-${user.email}`)), linkedAccounts.map((provider) => (jsx(LinkedProvider, { provider: provider }, `${provider.provider}-${provider.accountId}`))), user.phoneNumber && (jsx(LinkedProvider, { provider: {
14883
+ provider: 'phone',
14884
+ accountId: user.phoneNumber,
14885
+ } }, `phone-${user.phoneNumber}`))] }), jsx(AddLinkedProviderButton, {})] }));
14207
14886
  };
14208
14887
  const LinkedProviders = () => {
14209
- return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Linked accounts" }), jsx(ModalContent, { children: jsx(ModalBody, { children: "Configure the linked accounts of your profile." }) }), jsx(LinkedProvidersGroup, {})] }));
14888
+ return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Authentication methods" }), jsx(LinkedProvidersGroup, {})] }));
14210
14889
  };
14211
14890
 
14212
14891
  const Loading = () => {
@@ -14382,76 +15061,386 @@ const MobileConnectors = () => {
14382
15061
  context.setRoute(routes.CONNECT_WITH_MOBILE);
14383
15062
  context.setConnector({ id: walletId });
14384
15063
  };
14385
- return (jsx(PageContent, { width: 312, onBack: routes.PROVIDERS, children: jsxs(Container, { children: [jsx(ModalContent, { style: { paddingBottom: 0 }, children: jsx(ScrollArea, { height: 340, children: jsxs(WalletList, { children: [walletsIdsToDisplay
14386
- .sort(
14387
- // sort by name
14388
- (a, b) => {
14389
- var _a, _b, _c, _d;
14390
- const walletA = walletConfigs[a];
14391
- const walletB = walletConfigs[b];
14392
- const nameA = (_b = (_a = walletA.name) !== null && _a !== void 0 ? _a : walletA.shortName) !== null && _b !== void 0 ? _b : a;
14393
- const nameB = (_d = (_c = walletB.name) !== null && _c !== void 0 ? _c : walletB.shortName) !== null && _d !== void 0 ? _d : b;
14394
- return nameA.localeCompare(nameB);
14395
- })
14396
- .filter((walletId) => !(walletId === 'coinbaseWallet' || walletId === 'com.coinbase.wallet'))
14397
- .map((walletId, i) => {
14398
- const wallet = walletConfigs[walletId];
14399
- const { name, shortName, iconConnector, icon } = wallet;
14400
- return (jsxs(WalletItem, { onClick: () => connectWallet(walletId), style: {
14401
- animationDelay: `${i * 50}ms`,
14402
- }, children: [jsx(WalletIcon, { "$outline": true, children: iconConnector !== null && iconConnector !== void 0 ? iconConnector : icon }), jsx(WalletLabel, { children: shortName !== null && shortName !== void 0 ? shortName : name })] }, walletId));
14403
- }), jsxs(WalletItem, { onClick: openW3M, "$waiting": isOpenW3M, children: [jsx(WalletIcon, { style: { background: 'var(--ck-body-background-secondary)' }, children: isOpenW3M ? (jsx("div", { style: {
14404
- position: 'absolute',
14405
- inset: 0,
14406
- display: 'flex',
14407
- alignItems: 'center',
14408
- justifyContent: 'center',
14409
- }, children: jsx("div", { style: {
14410
- width: '50%',
14411
- }, children: jsx(Spinner$3, {}) }) })) : (MoreIcon) }), jsx(WalletLabel, { children: locales.more })] })] }) }) }), context.uiConfig.walletConnectCTA !== 'modal' && (jsx("div", { style: {
14412
- display: 'flex',
14413
- alignItems: 'center',
14414
- justifyContent: 'center',
14415
- gap: 14,
14416
- paddingTop: 8,
14417
- }, children: jsx(CopyButton, { value: "", children: locales.copyToClipboard }) }))] }) }));
15064
+ return (jsx(PageContent, { width: 312, onBack: routes.PROVIDERS, children: jsxs(Container, { children: [jsx(ModalContent, { style: { paddingBottom: 0 }, children: jsx(ScrollArea, { height: 340, children: jsxs(WalletList, { children: [walletsIdsToDisplay
15065
+ .sort(
15066
+ // sort by name
15067
+ (a, b) => {
15068
+ var _a, _b, _c, _d;
15069
+ const walletA = walletConfigs[a];
15070
+ const walletB = walletConfigs[b];
15071
+ const nameA = (_b = (_a = walletA.name) !== null && _a !== void 0 ? _a : walletA.shortName) !== null && _b !== void 0 ? _b : a;
15072
+ const nameB = (_d = (_c = walletB.name) !== null && _c !== void 0 ? _c : walletB.shortName) !== null && _d !== void 0 ? _d : b;
15073
+ return nameA.localeCompare(nameB);
15074
+ })
15075
+ .filter((walletId) => !(walletId === 'coinbaseWallet' || walletId === 'com.coinbase.wallet'))
15076
+ .map((walletId, i) => {
15077
+ const wallet = walletConfigs[walletId];
15078
+ const { name, shortName, iconConnector, icon } = wallet;
15079
+ return (jsxs(WalletItem, { onClick: () => connectWallet(walletId), style: {
15080
+ animationDelay: `${i * 50}ms`,
15081
+ }, children: [jsx(WalletIcon, { "$outline": true, children: iconConnector !== null && iconConnector !== void 0 ? iconConnector : icon }), jsx(WalletLabel, { children: shortName !== null && shortName !== void 0 ? shortName : name })] }, walletId));
15082
+ }), jsxs(WalletItem, { onClick: openW3M, "$waiting": isOpenW3M, children: [jsx(WalletIcon, { style: { background: 'var(--ck-body-background-secondary)' }, children: isOpenW3M ? (jsx("div", { style: {
15083
+ position: 'absolute',
15084
+ inset: 0,
15085
+ display: 'flex',
15086
+ alignItems: 'center',
15087
+ justifyContent: 'center',
15088
+ }, children: jsx("div", { style: {
15089
+ width: '50%',
15090
+ }, children: jsx(Spinner$3, {}) }) })) : (MoreIcon) }), jsx(WalletLabel, { children: locales.more })] })] }) }) }), context.uiConfig.walletConnectCTA !== 'modal' && (jsx("div", { style: {
15091
+ display: 'flex',
15092
+ alignItems: 'center',
15093
+ justifyContent: 'center',
15094
+ gap: 14,
15095
+ paddingTop: 8,
15096
+ }, children: jsx(CopyButton, { value: "", children: locales.copyToClipboard }) }))] }) }));
15097
+ };
15098
+
15099
+ const ButtonsContainer = styled.div `
15100
+ display: flex;
15101
+ gap: 12px;
15102
+ margin-top: 12px;
15103
+ `;
15104
+
15105
+ const NoAssetsAvailable = () => {
15106
+ const { setRoute } = useOpenfort();
15107
+ const chainId = useChainId();
15108
+ const chains = useChains();
15109
+ const chain = chains.find((c) => c.id === chainId);
15110
+ const showBuyOption = chain && !chain.testnet;
15111
+ return (jsxs(PageContent, { children: [jsx(FloatingGraphic, { height: "190px", logoCenter: {
15112
+ logo: jsx(BuyIcon, {}),
15113
+ }, logoTopLeft: {
15114
+ logo: jsx(BuyIcon, {}),
15115
+ }, logoBottomRight: {
15116
+ logo: jsx(BuyIcon, {}),
15117
+ }, logoTopRight: {
15118
+ logo: jsx(DollarIcon, {}),
15119
+ }, logoBottomLeft: {
15120
+ logo: jsx(DollarIcon, {}),
15121
+ } }), jsxs(ModalContent, { style: { paddingBottom: 0 }, children: [jsx(ModalH1, { "$small": true, children: "No assets available" }), jsxs(ModalBody, { children: [jsx("div", { style: { paddingRight: 12, paddingLeft: 12 }, children: "You currently have no assets available in your wallet." }), jsxs(ButtonsContainer, { children: [jsx(Button, { onClick: () => {
15122
+ setRoute(routes.RECEIVE);
15123
+ }, icon: jsx(ReceiveIcon, {}), children: "Get assets" }), showBuyOption && (jsx(Button, { onClick: () => {
15124
+ setRoute(routes.BUY);
15125
+ }, icon: jsx(BuyIcon, {}), children: "Buy assets" }))] })] })] })] }));
15126
+ };
15127
+
15128
+ const Introduction = () => {
15129
+ var _a;
15130
+ const context = useOpenfort();
15131
+ const locales = useLocales({});
15132
+ const ctaUrl = (_a = context.uiConfig.walletOnboardingUrl) !== null && _a !== void 0 ? _a : locales.onboardingScreen_ctaUrl;
15133
+ return (jsxs(PageContent, { children: [jsxs(Graphic, { children: [jsxs(LogoGroup, { children: [jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.Coinbase, { background: true }) }) }) }) }) }) }), jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.MetaMask, { background: true }) }) }) }) }) }) }), jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.Trust, {}) }) }) }) }) }) }), jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.Argent, {}) }) }) }) }) }) }), jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.ImToken, {}) }) }) }) }) }) })] }), jsx(GraphicBackground, { children: wave })] }), jsxs(ModalContent, { style: { paddingBottom: 18 }, children: [jsx(ModalH1, { "$small": true, children: locales.onboardingScreen_h1 }), jsx(ModalBody, { children: locales.onboardingScreen_p })] }), jsx(Button, { href: ctaUrl, arrow: true, children: locales.onboardingScreen_ctaText })] }));
15134
+ };
15135
+
15136
+ const usePhoneOtpAuth = (hookOptions = {}) => {
15137
+ const { client, updateUser } = useOpenfortCore();
15138
+ const [status, setStatus] = useState({
15139
+ status: 'idle',
15140
+ });
15141
+ const reset = useCallback(() => {
15142
+ setStatus({
15143
+ status: 'idle',
15144
+ });
15145
+ }, []);
15146
+ const { tryUseWallet } = useConnectToWalletPostAuth();
15147
+ const logInWithPhoneOtp = useCallback(async (options) => {
15148
+ var _a, _b;
15149
+ try {
15150
+ setStatus({
15151
+ status: 'loading',
15152
+ });
15153
+ if (!options.phoneNumber || !options.otp) {
15154
+ const error = new OpenfortError('Phone and OTP are required', OpenfortReactErrorType.VALIDATION_ERROR);
15155
+ setStatus({
15156
+ status: 'error',
15157
+ error,
15158
+ });
15159
+ return onError({
15160
+ hookOptions,
15161
+ options,
15162
+ error,
15163
+ });
15164
+ }
15165
+ const result = await client.auth.logInWithPhoneOtp({
15166
+ phoneNumber: options.phoneNumber,
15167
+ otp: options.otp,
15168
+ });
15169
+ const { wallet } = await tryUseWallet({
15170
+ logoutOnError: (_a = options.logoutOnError) !== null && _a !== void 0 ? _a : hookOptions.logoutOnError,
15171
+ recoverWalletAutomatically: (_b = options.recoverWalletAutomatically) !== null && _b !== void 0 ? _b : hookOptions.recoverWalletAutomatically,
15172
+ });
15173
+ setStatus({
15174
+ status: 'success',
15175
+ });
15176
+ const user = result.user;
15177
+ await updateUser();
15178
+ return onSuccess({
15179
+ data: { user, wallet },
15180
+ hookOptions,
15181
+ options,
15182
+ });
15183
+ }
15184
+ catch (e) {
15185
+ const error = new OpenfortError('Failed to login with phone OTP', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
15186
+ error: e,
15187
+ });
15188
+ setStatus({
15189
+ status: 'error',
15190
+ error: error,
15191
+ });
15192
+ return onError({
15193
+ hookOptions,
15194
+ options,
15195
+ error: error,
15196
+ });
15197
+ }
15198
+ }, [client, setStatus, updateUser, hookOptions]);
15199
+ const requestPhoneOtp = useCallback(async (options) => {
15200
+ try {
15201
+ setStatus({
15202
+ status: 'requesting',
15203
+ });
15204
+ if (!options.phoneNumber) {
15205
+ const error = new OpenfortError('Phone number is required', OpenfortReactErrorType.VALIDATION_ERROR);
15206
+ setStatus({
15207
+ status: 'error',
15208
+ error,
15209
+ });
15210
+ return onError({
15211
+ hookOptions,
15212
+ options,
15213
+ error,
15214
+ });
15215
+ }
15216
+ await client.auth.requestPhoneOtp({
15217
+ phoneNumber: options.phoneNumber,
15218
+ });
15219
+ setStatus({
15220
+ status: 'idle',
15221
+ });
15222
+ return onSuccess({
15223
+ data: {},
15224
+ hookOptions,
15225
+ options,
15226
+ });
15227
+ }
15228
+ catch (e) {
15229
+ const error = new OpenfortError('Failed to request phone OTP', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
15230
+ error: e,
15231
+ });
15232
+ setStatus({
15233
+ status: 'error',
15234
+ error: error,
15235
+ });
15236
+ return onError({
15237
+ hookOptions,
15238
+ options,
15239
+ error: error,
15240
+ });
15241
+ }
15242
+ }, [client, setStatus, updateUser, hookOptions]);
15243
+ const linkPhoneOtp = useCallback(async (options) => {
15244
+ try {
15245
+ setStatus({
15246
+ status: 'loading',
15247
+ });
15248
+ if (!options.phoneNumber || !options.otp) {
15249
+ const error = new OpenfortError('Phone and OTP are required', OpenfortReactErrorType.VALIDATION_ERROR);
15250
+ setStatus({
15251
+ status: 'error',
15252
+ error,
15253
+ });
15254
+ return onError({
15255
+ hookOptions,
15256
+ options,
15257
+ error,
15258
+ });
15259
+ }
15260
+ const result = await client.auth.linkPhoneOtp({
15261
+ phoneNumber: options.phoneNumber,
15262
+ otp: options.otp,
15263
+ });
15264
+ setStatus({
15265
+ status: 'success',
15266
+ });
15267
+ const user = result.user;
15268
+ await updateUser();
15269
+ return onSuccess({
15270
+ data: { user },
15271
+ hookOptions,
15272
+ options,
15273
+ });
15274
+ }
15275
+ catch (e) {
15276
+ const error = new OpenfortError('Failed to link phone OTP', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
15277
+ error: e,
15278
+ });
15279
+ setStatus({
15280
+ status: 'error',
15281
+ error: error,
15282
+ });
15283
+ return onError({
15284
+ hookOptions,
15285
+ options,
15286
+ error: error,
15287
+ });
15288
+ }
15289
+ }, [client, setStatus, updateUser, hookOptions]);
15290
+ return {
15291
+ logInWithPhoneOtp,
15292
+ requestPhoneOtp,
15293
+ linkPhoneOtp,
15294
+ reset,
15295
+ isRequesting: status.status === 'requesting',
15296
+ ...mapStatus(status),
15297
+ isAwaitingInput: status.status === 'awaiting-input',
15298
+ };
14418
15299
  };
14419
15300
 
14420
- const ButtonsContainer = styled.div `
14421
- display: flex;
14422
- gap: 12px;
14423
- margin-top: 12px;
15301
+ const Body = styled.p `
15302
+ color: var(--ck-body-color);
15303
+ text-align: center;
15304
+ margin-bottom: 16px;
15305
+ `;
15306
+ const ResultContainer = styled.div `
15307
+ margin-top: 16px;
15308
+ height: 24px;
15309
+ text-align: center;
14424
15310
  `;
15311
+ const FooterButtonText = styled.button `
15312
+ background: none;
15313
+ border: none;
15314
+ cursor: pointer;
15315
+ padding: 0;
15316
+ color: var(--ck-body-color-muted);
15317
+ transition: color 0.3s;
14425
15318
 
14426
- const NoAssetsAvailable = () => {
14427
- const { setRoute } = useOpenfort();
14428
- const chainId = useChainId();
14429
- const chains = useChains();
14430
- const chain = chains.find((c) => c.id === chainId);
14431
- const showBuyOption = chain && !chain.testnet;
14432
- return (jsxs(PageContent, { children: [jsx(FloatingGraphic, { height: "190px", logoCenter: {
14433
- logo: jsx(BuyIcon, {}),
14434
- }, logoTopLeft: {
14435
- logo: jsx(BuyIcon, {}),
14436
- }, logoBottomRight: {
14437
- logo: jsx(BuyIcon, {}),
14438
- }, logoTopRight: {
14439
- logo: jsx(DollarIcon, {}),
14440
- }, logoBottomLeft: {
14441
- logo: jsx(DollarIcon, {}),
14442
- } }), jsxs(ModalContent, { style: { paddingBottom: 0 }, children: [jsx(ModalH1, { "$small": true, children: "No assets available" }), jsxs(ModalBody, { children: [jsx("div", { style: { paddingRight: 12, paddingLeft: 12 }, children: "You currently have no assets available in your wallet." }), jsxs(ButtonsContainer, { children: [jsx(Button, { onClick: () => {
14443
- setRoute(routes.RECEIVE);
14444
- }, icon: jsx(ReceiveIcon, {}), children: "Get assets" }), showBuyOption && (jsx(Button, { onClick: () => {
14445
- setRoute(routes.BUY);
14446
- }, icon: jsx(BuyIcon, {}), children: "Buy assets" }))] })] })] })] }));
14447
- };
15319
+ &:disabled {
15320
+ color: var(--ck-body-color-muted) !important;
15321
+ cursor: not-allowed;
15322
+ }
15323
+ `;
15324
+ const FooterTextButton = styled.p `
15325
+ color: var(--ck-body-color-muted);
15326
+ text-align: center;
15327
+ margin-top: 16px;
15328
+ &:hover {
15329
+ ${FooterButtonText} {
15330
+ color: var(--ck-body-color);
15331
+ }
15332
+ }
15333
+ `;
14448
15334
 
14449
- const Introduction = () => {
14450
- var _a;
14451
- const context = useOpenfort();
14452
- const locales = useLocales({});
14453
- const ctaUrl = (_a = context.uiConfig.walletOnboardingUrl) !== null && _a !== void 0 ? _a : locales.onboardingScreen_ctaUrl;
14454
- return (jsxs(PageContent, { children: [jsxs(Graphic, { children: [jsxs(LogoGroup, { children: [jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.Coinbase, { background: true }) }) }) }) }) }) }), jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.MetaMask, { background: true }) }) }) }) }) }) }), jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.Trust, {}) }) }) }) }) }) }), jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.Argent, {}) }) }) }) }) }) }), jsx(Logo$1, { children: jsx(LogoPosition, { children: jsx(LogoInner, { children: jsx(FloatWrapper, { children: jsx(RotateWrapper, { children: jsx(LogoGraphic$1, { children: jsx(Logos.ImToken, {}) }) }) }) }) }) })] }), jsx(GraphicBackground, { children: wave })] }), jsxs(ModalContent, { style: { paddingBottom: 18 }, children: [jsx(ModalH1, { "$small": true, children: locales.onboardingScreen_h1 }), jsx(ModalBody, { children: locales.onboardingScreen_p })] }), jsx(Button, { href: ctaUrl, arrow: true, children: locales.onboardingScreen_ctaText })] }));
15335
+ const RESEND_COOLDOWN_MS = 10000;
15336
+ const SUCCESS_REDIRECT_DELAY_MS = 2000;
15337
+ const ERROR_DISPLAY_DURATION_MS = 2000;
15338
+ const PhoneOTP = () => {
15339
+ const { phoneInput: phone, setPhoneInput, setRoute } = useOpenfort();
15340
+ const { isLoading, requestPhoneOtp, logInWithPhoneOtp, linkPhoneOtp } = usePhoneOtpAuth({
15341
+ recoverWalletAutomatically: false,
15342
+ });
15343
+ const { user } = useUser();
15344
+ const [canSendOtp, setCanSendOtp] = useState(true);
15345
+ const [status, setStatus] = useState('idle');
15346
+ const [errorMessage, setErrorMessage] = useState(null);
15347
+ // Single ref to track if initial OTP request has been made
15348
+ const hasRequestedInitialOtpRef = useRef(false);
15349
+ // Memoize the OTP request function to prevent unnecessary recreations
15350
+ const sendOtpRequest = useCallback(async () => {
15351
+ const { error } = await requestPhoneOtp({ phoneNumber: phone });
15352
+ if (error) {
15353
+ logger.error('Error requesting phone OTP:', error);
15354
+ setStatus('error');
15355
+ }
15356
+ else {
15357
+ setStatus('idle');
15358
+ }
15359
+ }, [phone, requestPhoneOtp]);
15360
+ // Initial OTP request on mount
15361
+ useEffect(() => {
15362
+ if (hasRequestedInitialOtpRef.current)
15363
+ return;
15364
+ hasRequestedInitialOtpRef.current = true;
15365
+ sendOtpRequest();
15366
+ }, [sendOtpRequest]);
15367
+ // Handle OTP completion
15368
+ const handleComplete = useCallback(async (otp) => {
15369
+ logger.log('OTP entered:', otp);
15370
+ setStatus('loading');
15371
+ let error = null;
15372
+ if (user) {
15373
+ const { error: linkError } = await linkPhoneOtp({ phoneNumber: phone, otp });
15374
+ error = linkError;
15375
+ }
15376
+ else {
15377
+ const { error: loginError } = await logInWithPhoneOtp({ phoneNumber: phone, otp });
15378
+ error = loginError;
15379
+ }
15380
+ if (error) {
15381
+ logger.error('Error verifying phone OTP:', error);
15382
+ setStatus('error');
15383
+ if (error.message === 'Invalid OTP') {
15384
+ setErrorMessage('Invalid code. Please try again.');
15385
+ }
15386
+ else {
15387
+ setErrorMessage(error.message);
15388
+ }
15389
+ }
15390
+ else {
15391
+ setStatus('success');
15392
+ }
15393
+ }, [phone, logInWithPhoneOtp]);
15394
+ // Handle status changes and side effects
15395
+ useEffect(() => {
15396
+ let timeoutId;
15397
+ switch (status) {
15398
+ case 'send-otp':
15399
+ setStatus('sending-otp');
15400
+ sendOtpRequest();
15401
+ break;
15402
+ case 'success':
15403
+ timeoutId = setTimeout(() => {
15404
+ setPhoneInput('');
15405
+ setRoute(routes.LOAD_WALLETS);
15406
+ }, SUCCESS_REDIRECT_DELAY_MS);
15407
+ break;
15408
+ case 'error':
15409
+ timeoutId = setTimeout(() => {
15410
+ setStatus('idle');
15411
+ }, ERROR_DISPLAY_DURATION_MS);
15412
+ break;
15413
+ }
15414
+ return () => {
15415
+ if (timeoutId)
15416
+ clearTimeout(timeoutId);
15417
+ };
15418
+ }, [status, sendOtpRequest, setPhoneInput, setRoute]);
15419
+ // Handle resend cooldown
15420
+ useEffect(() => {
15421
+ if (canSendOtp)
15422
+ return;
15423
+ const timerId = setTimeout(() => {
15424
+ setCanSendOtp(true);
15425
+ }, RESEND_COOLDOWN_MS);
15426
+ return () => clearTimeout(timerId);
15427
+ }, [canSendOtp]);
15428
+ // Memoize button text to avoid recalculation
15429
+ const sendButtonText = useMemo(() => {
15430
+ if (!canSendOtp)
15431
+ return 'Code Sent!';
15432
+ if (status === 'sending-otp')
15433
+ return 'Sending...';
15434
+ return 'Resend Code';
15435
+ }, [canSendOtp, status]);
15436
+ const handleResendClick = useCallback(() => {
15437
+ setStatus('send-otp');
15438
+ setCanSendOtp(false);
15439
+ }, []);
15440
+ const isResendDisabled = !canSendOtp || status === 'sending-otp' || status === 'send-otp';
15441
+ return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Enter your code" }), jsx(FloatingGraphic, { height: "100px", marginTop: "8px", marginBottom: "10px", logoCenter: {
15442
+ logo: jsx(PhoneIcon, {}),
15443
+ } }), jsxs(ModalBody, { children: [jsxs(Body, { children: ["Please check ", jsx("b", { children: phone }), " for an SMS and enter your code below."] }), jsx(OtpInputStandalone, { onComplete: handleComplete, isLoading: status === 'loading' || isLoading, isError: status === 'error', isSuccess: status === 'success' }), jsxs(ResultContainer, { children: [status === 'success' && jsx(ModalBody, { "$valid": true, children: "Code verified successfully!" }), status === 'error' && jsx(ModalBody, { "$error": true, children: errorMessage || 'Invalid code. Please try again.' })] }), jsxs(FooterTextButton, { children: ["Didn't receive the code?", ' ', jsx(FooterButtonText, { type: "button", onClick: handleResendClick, disabled: isResendDisabled, children: sendButtonText })] })] }), jsx(PoweredByFooter, {})] }));
14455
15444
  };
14456
15445
 
14457
15446
  const LargeButtonStyle = styled.div `
@@ -14538,12 +15527,12 @@ const Profile = () => {
14538
15527
  }, [shouldDisconnect]);
14539
15528
  return (jsxs(PageContent, { onBack: routes.CONNECTED, children: [jsxs(ModalContent, { children: [jsx(ModalHeading, { children: "Profile" }), jsxs("div", { children: [jsx(LargeButton, { onClick: () => {
14540
15529
  setRoute(routes.LINKED_PROVIDERS);
14541
- }, icon: jsx(GuestIcon, {}), children: "Linked accounts" }), jsx(LargeButton, { onClick: () => {
15530
+ }, icon: jsx(GuestIcon, {}), children: "Authentication methods" }), jsx(LargeButton, { onClick: () => {
14542
15531
  setRoute(routes.EXPORT_KEY);
14543
15532
  }, icon: jsx(KeyIcon, {}), children: "Export key" })] })] }), !isSafeConnector(connector === null || connector === void 0 ? void 0 : connector.id) && (jsx(DisconnectButton, { onClick: () => setShouldDisconnect(true), icon: jsx(DisconnectIcon, {}), children: locales.disconnect }))] }));
14544
15533
  };
14545
15534
 
14546
- const ProviderButton = ({ children, icon, onClick }) => {
15535
+ const ProviderButtonBase = ({ children, icon, onClick }) => {
14547
15536
  return (jsx(ProvidersButton, { children: jsxs(Button, { onClick: onClick, children: [jsx(ProviderLabel, { children: children }), jsx(ProviderIcon$1, { children: icon })] }) }));
14548
15537
  };
14549
15538
  const GuestButton = () => {
@@ -14551,22 +15540,57 @@ const GuestButton = () => {
14551
15540
  const handleClick = () => {
14552
15541
  setRoute(routes.CREATE_GUEST_USER);
14553
15542
  };
14554
- return (jsx(ProviderButton, { onClick: handleClick, icon: jsx(GuestIcon, {}), children: "Guest" }));
15543
+ return (jsx(ProviderButtonBase, { onClick: handleClick, icon: jsx(GuestIcon, {}), children: "Guest" }));
14555
15544
  };
14556
15545
  const WalletButton = () => {
14557
15546
  const { setRoute } = useOpenfort();
14558
15547
  const { user } = useOpenfortCore();
14559
- return (jsx(ProviderButton, { onClick: () => setRoute({ route: routes.CONNECTORS, connectType: user ? 'link' : 'connect' }), icon: jsx(Logos.OtherWallets, {}), children: "Wallet" }));
15548
+ return (jsx(ProviderButtonBase, { onClick: () => setRoute({ route: routes.CONNECTORS, connectType: user ? 'link' : 'connect' }), icon: jsx(Logos.OtherWallets, {}), children: "Wallet" }));
14560
15549
  };
14561
- const EmailButton = () => {
15550
+ const EmailButton = ({ handleSubmit }) => {
15551
+ const { emailInput, setEmailInput } = useOpenfort();
15552
+ const isValidEmail$1 = useMemo(() => {
15553
+ return isValidEmail(emailInput);
15554
+ }, [emailInput]);
15555
+ return (jsx(ProvidersButton, { children: jsx("form", { onSubmit: (e) => {
15556
+ e.preventDefault();
15557
+ if (isValidEmail$1)
15558
+ handleSubmit();
15559
+ }, noValidate: true, children: jsxs(ProviderInputInner, { children: [jsx("input", { value: emailInput, onChange: (e) => setEmailInput(e.target.value), type: "email", placeholder: "Enter your email", formNoValidate: true }), jsx("div", { style: { position: 'relative' }, children: jsx(AnimatePresence, { initial: false, children: isValidEmail$1 ? (jsx(motion.div, { initial: { x: -5, opacity: 0 }, animate: { x: 0, opacity: 1 }, exit: { x: -5, opacity: 0, position: 'absolute' }, transition: { duration: 0.2, ease: [0.25, 1, 0.5, 1] }, children: jsx(EmailInnerButton, { type: "submit", "aria-label": "Submit email", children: jsx(ProviderIcon$1, { children: jsxs("svg", { width: "13", height: "12", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("title", { children: "Submit email" }), jsx("line", { stroke: "currentColor", x1: "1", y1: "6", x2: "12", y2: "6", strokeWidth: "1", strokeLinecap: "round" }), jsx("path", { stroke: "currentColor", d: "M7.51431 1.5L11.757 5.74264M7.5 10.4858L11.7426 6.24314", strokeWidth: "1", strokeLinecap: "round" })] }) }) }) }, emailInput ? 'enabled' : 'disabled')) : (jsx(motion.div, { initial: { x: 5, opacity: 0 }, animate: { x: 0, opacity: 1 }, exit: { x: 5, opacity: 0, position: 'absolute' }, transition: { duration: 0.2, ease: [0.25, 1, 0.5, 1] }, children: jsx(ProviderIcon$1, { children: jsx(EmailIcon, {}) }) })) }) })] }) }) }));
15560
+ };
15561
+ const EmailPasswordButton = () => {
14562
15562
  const { setRoute } = useOpenfort();
14563
15563
  const { user } = useOpenfortCore();
14564
- const { emailInput, setEmailInput } = useOpenfort();
15564
+ const handleSubmit = () => {
15565
+ setRoute(user ? routes.LINK_EMAIL : routes.EMAIL_LOGIN);
15566
+ };
15567
+ return jsx(EmailButton, { handleSubmit: handleSubmit });
15568
+ };
15569
+ const EmailOTPButton = () => {
15570
+ const { setRoute } = useOpenfort();
15571
+ const handleSubmit = () => {
15572
+ setRoute(routes.EMAIL_OTP);
15573
+ };
15574
+ return jsx(EmailButton, { handleSubmit: handleSubmit });
15575
+ };
15576
+ const PhoneButton = () => {
15577
+ const { uiConfig, phoneInput, setPhoneInput, setRoute } = useOpenfort();
14565
15578
  const handleSubmit = (e) => {
14566
15579
  e.preventDefault();
14567
- setRoute(user ? routes.LINK_EMAIL : routes.EMAIL_LOGIN);
15580
+ setRoute(routes.PHONE_OTP);
14568
15581
  };
14569
- return (jsx(ProvidersButton, { children: jsx("form", { onSubmit: handleSubmit, noValidate: true, children: jsxs(ProviderInputInner, { children: [jsx("input", { value: emailInput, onChange: (e) => setEmailInput(e.target.value), type: "email", placeholder: "Enter your email", formNoValidate: true }), jsx("div", { style: { position: 'relative' }, children: jsx(AnimatePresence, { initial: false, children: emailInput ? (jsx(EmailInnerButton, { initial: { x: -5, opacity: 0 }, animate: { x: 0, opacity: 1 }, exit: { x: -5, opacity: 0, position: 'absolute' }, transition: { duration: 0.2, ease: [0.25, 1, 0.5, 1] }, type: "submit", "aria-label": "Submit email", children: jsx(ProviderIcon$1, { children: jsxs("svg", { width: "13", height: "12", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("title", { children: "Submit email" }), jsx("line", { stroke: "currentColor", x1: "1", y1: "6", x2: "12", y2: "6", strokeWidth: "1", strokeLinecap: "round" }), jsx("path", { stroke: "currentColor", d: "M7.51431 1.5L11.757 5.74264M7.5 10.4858L11.7426 6.24314", strokeWidth: "1", strokeLinecap: "round" })] }) }) }, emailInput ? 'enabled' : 'disabled')) : (jsx(motion.div, { initial: { x: 5, opacity: 0 }, animate: { x: 0, opacity: 1 }, exit: { x: 5, opacity: 0, position: 'absolute' }, transition: { duration: 0.2, ease: [0.25, 1, 0.5, 1] }, children: jsx(ProviderIcon$1, { children: jsx(EmailIcon, {}) }) })) }) })] }) }) }));
15582
+ const hasValue = phoneInput.length > 5;
15583
+ // && !defaultCountries.some((country: CountryData) => phoneInput.replace('+', '') === country[2])
15584
+ return (jsx(ProvidersButton, { children: jsx("form", { onSubmit: handleSubmit, noValidate: true, children: jsxs(ProviderInputInner, { children: [jsx("div", { style: { width: '100%' }, children: jsx(PhoneInput, { value: phoneInput, onChange: (phone) => setPhoneInput(phone), hideDropdown: false, placeholder: "Enter your phone", style: {
15585
+ '--react-international-phone-height': '56px',
15586
+ '--react-international-phone-text-color': 'var(--ck-body-color)',
15587
+ '--react-international-phone-background-color': 'var(--ck-secondary-button-background)',
15588
+ '--react-international-phone-country-selector-background-color': 'var(--ck-secondary-button-background)',
15589
+ '--react-international-phone-selected-dropdown-item-background-color': 'var(--ck-secondary-button-hover-background)',
15590
+ '--react-international-phone-country-selector-background-color-hover': 'var(--ck-secondary-button-hover-background)',
15591
+ '--react-international-phone-font-size': '16px',
15592
+ paddingLeft: '4px',
15593
+ }, ...uiConfig.phoneConfig }) }), jsx("div", { style: { position: 'relative' }, children: jsx(AnimatePresence, { initial: false, children: hasValue ? (jsx(EmailInnerButton, { initial: { x: -5, opacity: 0 }, animate: { x: 0, opacity: 1 }, exit: { x: -5, opacity: 0, position: 'absolute' }, transition: { duration: 0.2, ease: [0.25, 1, 0.5, 1] }, type: "submit", "aria-label": "Submit email", children: jsx(ProviderIcon$1, { children: jsxs("svg", { width: "13", height: "12", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("title", { children: "Submit email" }), jsx("line", { stroke: "currentColor", x1: "1", y1: "6", x2: "12", y2: "6", strokeWidth: "1", strokeLinecap: "round" }), jsx("path", { stroke: "currentColor", d: "M7.51431 1.5L11.757 5.74264M7.5 10.4858L11.7426 6.24314", strokeWidth: "1", strokeLinecap: "round" })] }) }) }, phoneInput ? 'enabled' : 'disabled')) : (jsx(motion.div, { initial: { x: 5, opacity: 0 }, animate: { x: 0, opacity: 1 }, exit: { x: 5, opacity: 0, position: 'absolute' }, transition: { duration: 0.2, ease: [0.25, 1, 0.5, 1] }, children: jsx(ProviderIcon$1, { children: jsx(PhoneIcon, {}) }) })) }) })] }) }) }));
14570
15594
  };
14571
15595
  const AuthProviderButton = ({ provider, title = `${provider} login`, icon, }) => {
14572
15596
  const { setRoute, setConnector } = useOpenfort();
@@ -14574,29 +15598,26 @@ const AuthProviderButton = ({ provider, title = `${provider} login`, icon, }) =>
14574
15598
  setRoute({ route: routes.CONNECT, connectType: 'linkIfUserConnectIfNoUser' });
14575
15599
  setConnector({ id: provider, type: 'oauth' });
14576
15600
  };
14577
- return (jsx(ProviderButton, { onClick: handleClick, icon: icon, children: title }));
15601
+ return (jsx(ProviderButtonBase, { onClick: handleClick, icon: icon, children: title }));
14578
15602
  };
14579
- const ProviderButtonSwitch = ({ provider }) => {
14580
- switch (provider) {
14581
- case UIAuthProvider.GUEST:
14582
- return jsx(GuestButton, {});
14583
- case UIAuthProvider.WALLET:
14584
- return jsx(WalletButton, {});
14585
- case UIAuthProvider.EMAIL:
14586
- return jsx(EmailButton, {});
14587
- case UIAuthProvider.GOOGLE:
14588
- return jsx(AuthProviderButton, { provider: OAuthProvider.GOOGLE, title: "Google", icon: providersLogos[provider] });
14589
- case UIAuthProvider.TWITTER:
14590
- return jsx(AuthProviderButton, { provider: OAuthProvider.TWITTER, title: "X", icon: providersLogos[provider] });
14591
- case UIAuthProvider.FACEBOOK:
14592
- return jsx(AuthProviderButton, { provider: OAuthProvider.FACEBOOK, title: "Facebook", icon: providersLogos[provider] });
14593
- case UIAuthProvider.DISCORD:
14594
- return jsx(AuthProviderButton, { provider: OAuthProvider.DISCORD, title: "Discord", icon: providersLogos[provider] });
14595
- case UIAuthProvider.APPLE:
14596
- return jsx(AuthProviderButton, { provider: OAuthProvider.APPLE, title: "Apple", icon: providersLogos[provider] });
14597
- default:
14598
- throw new Error(`NOT IMPLEMENTED: ${provider}`);
15603
+ const authProviderToOAuthProviderMap = {
15604
+ guest: jsx(GuestButton, {}),
15605
+ wallet: jsx(WalletButton, {}),
15606
+ emailPassword: jsx(EmailPasswordButton, {}),
15607
+ emailOtp: jsx(EmailOTPButton, {}),
15608
+ phone: jsx(PhoneButton, {}),
15609
+ google: (jsx(AuthProviderButton, { provider: OAuthProvider.GOOGLE, title: "Google", icon: providersLogos[UIAuthProvider.GOOGLE] })),
15610
+ twitter: (jsx(AuthProviderButton, { provider: OAuthProvider.TWITTER, title: "X", icon: providersLogos[UIAuthProvider.TWITTER] })),
15611
+ facebook: (jsx(AuthProviderButton, { provider: OAuthProvider.FACEBOOK, title: "Facebook", icon: providersLogos[UIAuthProvider.FACEBOOK] })),
15612
+ discord: (jsx(AuthProviderButton, { provider: OAuthProvider.DISCORD, title: "Discord", icon: providersLogos[UIAuthProvider.DISCORD] })),
15613
+ apple: (jsx(AuthProviderButton, { provider: OAuthProvider.APPLE, title: "Apple", icon: providersLogos[UIAuthProvider.APPLE] })),
15614
+ };
15615
+ const ProviderButton = ({ provider }) => {
15616
+ const { user } = useOpenfortCore();
15617
+ if (user && (provider === UIAuthProvider.EMAIL_OTP || provider === UIAuthProvider.EMAIL_PASSWORD)) {
15618
+ return jsx(EmailPasswordButton, {});
14599
15619
  }
15620
+ return authProviderToOAuthProviderMap[provider] || null;
14600
15621
  };
14601
15622
  // This accounts for the case where the user has an address but no user, which can happen if the user has not signed up yet, but logged in with a wallet
14602
15623
  const AddressButNoUserCase = () => {
@@ -14616,7 +15637,7 @@ const AddressButNoUserCase = () => {
14616
15637
  };
14617
15638
  const SocialProvidersButton = ({ thereAreSocialsAlready }) => {
14618
15639
  const { setRoute } = useOpenfort();
14619
- return (jsx(ProviderButton, { onClick: () => setRoute(routes.SOCIAL_PROVIDERS), icon: jsx(OtherSocials, {}), children: thereAreSocialsAlready ? 'Other socials' : 'Social providers' }));
15640
+ return (jsx(ProviderButtonBase, { onClick: () => setRoute(routes.SOCIAL_PROVIDERS), icon: jsx(OtherSocials, {}), children: thereAreSocialsAlready ? 'Other socials' : 'Social providers' }));
14620
15641
  };
14621
15642
  const Providers = () => {
14622
15643
  const { user } = useOpenfortCore();
@@ -14632,7 +15653,7 @@ const Providers = () => {
14632
15653
  if (address && !user) {
14633
15654
  return jsx(AddressButNoUserCase, {});
14634
15655
  }
14635
- return (jsxs(PageContent, { onBack: onBack, children: [jsx(ModalHeading, { children: user ? 'Link auth' : 'Connect' }), mainProviders.map((auth) => (jsx(ProviderButtonSwitch, { provider: auth }, auth))), hasExcessProviders && (jsx(SocialProvidersButton, { thereAreSocialsAlready: !!mainProviders.find((p) => socialProviders.includes(p)) })), jsx(PoweredByFooter, { showDisclaimer: true })] }));
15656
+ return (jsxs(PageContent, { onBack: onBack, children: [jsx(ModalHeading, { children: user ? 'Link auth' : 'Connect' }), mainProviders.map((auth) => (jsx(ProviderButton, { provider: auth }, auth))), hasExcessProviders && (jsx(SocialProvidersButton, { thereAreSocialsAlready: !!mainProviders.find((p) => socialProviders.includes(p)) })), jsx(PoweredByFooter, { showDisclaimer: true })] }));
14636
15657
  };
14637
15658
 
14638
15659
  const StyledButton = styled.button `
@@ -14897,6 +15918,125 @@ const RecoverPage = () => {
14897
15918
  return jsx(RecoverWallet, { wallet: wallet, onBack: onBack, logoutOnBack: logoutOnBack });
14898
15919
  };
14899
15920
 
15921
+ const ProviderIconContainer = styled.div `
15922
+ width: 100%;
15923
+ display: flex;
15924
+ align-items: center;
15925
+ justify-content: center;
15926
+ `;
15927
+ const ProviderIconWrapper = styled.div `
15928
+ width: 54px;
15929
+ height: 54px;
15930
+ flex-shrink: 0;
15931
+ display: flex;
15932
+ align-items: center;
15933
+ justify-content: center;
15934
+ background-color: var(--ck-body-background-secondary);
15935
+ border-radius: 28px;
15936
+ `;
15937
+ const ProviderIconInner = styled.div `
15938
+ width: 32px;
15939
+ height: 32px;
15940
+ flex-shrink: 0;
15941
+ display: flex;
15942
+ align-items: center;
15943
+ justify-content: center;
15944
+ `;
15945
+ const ButtonWrapper = styled.div `
15946
+ display: flex;
15947
+ gap: 12px;
15948
+ margin-top: 24px;
15949
+ `;
15950
+ const ErrorMessage$1 = styled.div `
15951
+ color: var(--ck-body-color-danger, #ff4d4f);
15952
+ margin-top: 16px;
15953
+ `;
15954
+ const RemoveLinkedProvider = () => {
15955
+ const { route, triggerResize, onBack, setOnBack, setRouteHistory, setRoute } = useOpenfort();
15956
+ const { client, updateUser } = useOpenfortCore();
15957
+ const [error, setError] = useState(null);
15958
+ const [isSuccess, setIsSuccess] = useState(false);
15959
+ const provider = useMemo(() => {
15960
+ if (route.route === 'removeLinkedProvider') {
15961
+ return route.provider;
15962
+ }
15963
+ throw new Error('No provider found in route');
15964
+ }, []);
15965
+ useEffect(() => {
15966
+ if (error)
15967
+ triggerResize();
15968
+ }, [error]);
15969
+ useEffect(() => {
15970
+ if (isSuccess) {
15971
+ updateUser();
15972
+ triggerResize();
15973
+ setOnBack(() => () => {
15974
+ setRouteHistory((prev) => {
15975
+ const newHistory = [...prev];
15976
+ newHistory.pop();
15977
+ newHistory.pop();
15978
+ if (newHistory.length > 0) {
15979
+ setRoute(newHistory[newHistory.length - 1]);
15980
+ }
15981
+ else {
15982
+ setRoute({ route: routes.CONNECTED });
15983
+ }
15984
+ return newHistory;
15985
+ });
15986
+ });
15987
+ }
15988
+ }, [isSuccess]);
15989
+ const handleRemove = async () => {
15990
+ if (provider.provider === 'siwe' || provider.provider === 'wallet')
15991
+ try {
15992
+ const result = await client.auth.unlinkWallet({
15993
+ address: provider.accountId,
15994
+ chainId: provider.chainId,
15995
+ });
15996
+ if (!result.success) {
15997
+ setError('Failed to remove linked provider. Please try again.');
15998
+ return;
15999
+ }
16000
+ else {
16001
+ setIsSuccess(true);
16002
+ }
16003
+ }
16004
+ catch (e) {
16005
+ if (e instanceof Error)
16006
+ setError(e.message);
16007
+ else {
16008
+ logger.error('Unexpected error removing linked provider:', e);
16009
+ setError('Failed to remove linked provider. Please try again.');
16010
+ }
16011
+ return;
16012
+ }
16013
+ else {
16014
+ try {
16015
+ const result = await client.auth.unlinkOAuth({
16016
+ provider: provider.provider,
16017
+ });
16018
+ if (!result.status) {
16019
+ setError('Failed to remove linked provider. Please try again.');
16020
+ return;
16021
+ }
16022
+ else {
16023
+ setIsSuccess(true);
16024
+ }
16025
+ }
16026
+ catch (e) {
16027
+ if (e instanceof Error)
16028
+ setError(e.message);
16029
+ else {
16030
+ logger.error('Unexpected error removing linked provider:', e);
16031
+ setError('Failed to remove linked provider. Please try again.');
16032
+ }
16033
+ return;
16034
+ }
16035
+ }
16036
+ };
16037
+ return (jsxs(PageContent, { children: [jsxs(ModalHeading, { children: ["Remove ", getProviderName(provider.provider)] }), jsxs(ModalContent, { style: { paddingBottom: 0 }, children: [jsx(ProviderIconContainer, { style: { marginBottom: '16px' }, children: jsx(ProviderIconWrapper, { children: jsx(ProviderIconInner, { children: jsx(ProviderIcon, { provider: provider }) }) }) }), isSuccess ? (jsxs(Fragment, { children: [jsx(ModalH1, { "$valid": true, children: "Success" }), jsxs(ModalBody, { children: ["Successfully removed", ' ', provider.provider === 'siwe' ? (jsxs("span", { children: [jsx("b", { children: jsx(WalletDisplay, { walletAddress: provider.accountId }) }), "."] })) : (jsxs(Fragment, { children: [jsx("b", { children: getProviderName(provider.provider) }), " as an authentication method."] }))] }), jsx(ButtonWrapper, { style: { marginTop: 0 }, children: jsx(Button, { onClick: () => onBack === null || onBack === void 0 ? void 0 : onBack(), children: "Back" }) })] })) : (jsxs(Fragment, { children: [jsxs("p", { children: ["Are you sure you want to remove", ' ', provider.provider === 'siwe' ? (jsxs(CopyText, { value: provider.accountId, children: [jsx("b", { children: jsx(WalletDisplay, { walletAddress: provider.accountId }) }), "?"] })) : (jsxs(Fragment, { children: [jsx("b", { children: getProviderName(provider.provider) }), "as an authentication method?"] }))] }), error && jsx(ErrorMessage$1, { children: error }), jsxs(ButtonWrapper, { style: { marginTop: 0 }, children: [jsx(Button, { onClick: () => onBack === null || onBack === void 0 ? void 0 : onBack(), children: "Cancel" }), jsx(Button, { onClick: handleRemove, children: "Remove" })] })] }))] })] }));
16038
+ };
16039
+
14900
16040
  const ZERO = BigInt(0);
14901
16041
  const usdFormatter$1 = new Intl.NumberFormat('en-US', {
14902
16042
  style: 'currency',
@@ -15942,7 +17082,7 @@ const SendConfirmation = () => {
15942
17082
 
15943
17083
  const SocialProviders = () => {
15944
17084
  const { remainingSocialProviders } = useProviders();
15945
- return (jsxs(PageContent, { children: [jsx(ScrollArea, { mobileDirection: 'horizontal', children: remainingSocialProviders.map((auth) => (jsx(ProviderButtonSwitch, { provider: auth }, auth))) }), jsx(PoweredByFooter, { showDisclaimer: true })] }));
17085
+ return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Other socials" }), jsx(ScrollArea, { mobileDirection: 'horizontal', children: remainingSocialProviders.map((auth) => (jsx(ProviderButton, { provider: auth }, auth))) }), jsx(PoweredByFooter, { showDisclaimer: true })] }));
15946
17086
  };
15947
17087
 
15948
17088
  const SwitchNetworks = () => {
@@ -15964,7 +17104,7 @@ const createSIWEMessage = (address, nonce, chainId) => createSiweMessage({
15964
17104
  statement: 'By signing, you are proving you own this wallet and logging in. This does not initiate a transaction or cost any fees.',
15965
17105
  uri: window.location.origin,
15966
17106
  version: '1',
15967
- chainId: chainId !== null && chainId !== void 0 ? chainId : sepolia.id,
17107
+ chainId: chainId,
15968
17108
  nonce,
15969
17109
  });
15970
17110
 
@@ -15977,7 +17117,8 @@ function useConnectWithSiwe() {
15977
17117
  const chainId = useChainId();
15978
17118
  const config = useConfig();
15979
17119
  const publicClient = usePublicClient();
15980
- const connectWithSiwe = useCallback(async ({ onError, onConnect, connectorType: propsConnectorType, walletClientType: propsWalletClientType, } = {}) => {
17120
+ const { signMessageAsync } = useSignMessage();
17121
+ const connectWithSiwe = useCallback(async ({ onError, onConnect, connectorType: propsConnectorType, walletClientType: propsWalletClientType, link = !!user, } = {}) => {
15981
17122
  var _a, _b;
15982
17123
  const connectorType = propsConnectorType !== null && propsConnectorType !== void 0 ? propsConnectorType : connector === null || connector === void 0 ? void 0 : connector.type;
15983
17124
  const walletClientType = propsWalletClientType !== null && propsWalletClientType !== void 0 ? propsWalletClientType : connector === null || connector === void 0 ? void 0 : connector.id;
@@ -15992,30 +17133,36 @@ function useConnectWithSiwe() {
15992
17133
  chainId,
15993
17134
  });
15994
17135
  }
15995
- const { nonce } = await client.auth.initSIWE({ address });
17136
+ let nonce;
17137
+ if (link) {
17138
+ const resp = await client.auth.linkSIWE({ address });
17139
+ nonce = resp.nonce;
17140
+ }
17141
+ else {
17142
+ const resp = await client.auth.initSIWE({ address });
17143
+ nonce = resp.nonce;
17144
+ }
15996
17145
  const SIWEMessage = createSIWEMessage(address, nonce, chainId);
15997
- const signature = await signMessage(config, { message: SIWEMessage });
15998
- // if has user, we link the wallet
15999
- if (user) {
16000
- logger.log('User found, trying to lint wallet to user');
16001
- const authToken = await client.getAccessToken();
16002
- if (!authToken)
16003
- throw new Error('No access token found');
16004
- logger.log('Linking wallet', { signature, message: SIWEMessage, connectorType, walletClientType, authToken });
17146
+ const signature = await signMessageAsync({ message: SIWEMessage });
17147
+ if (link) {
17148
+ logger.log('Linking wallet to user');
16005
17149
  await client.auth.linkWallet({
16006
17150
  signature,
16007
17151
  message: SIWEMessage,
16008
17152
  connectorType,
16009
17153
  walletClientType,
16010
- authToken,
17154
+ address,
17155
+ chainId,
16011
17156
  });
16012
17157
  }
16013
17158
  else {
17159
+ logger.log('Authenticating with SIWE');
16014
17160
  await client.auth.authenticateWithSIWE({
16015
17161
  signature,
16016
17162
  message: SIWEMessage,
16017
17163
  connectorType,
16018
17164
  walletClientType,
17165
+ address,
16019
17166
  });
16020
17167
  }
16021
17168
  await updateUser();
@@ -16041,7 +17188,7 @@ function useConnectWithSiwe() {
16041
17188
  else {
16042
17189
  message = 'Failed to connect with SIWE.';
16043
17190
  }
16044
- onError(message, err instanceof OpenfortError$1 ? err.type : undefined);
17191
+ onError(message, err instanceof OpenfortError$1 ? err : undefined);
16045
17192
  }
16046
17193
  }, [client, user, updateUser, address, chainId, config, connector, accountChainId, publicClient]);
16047
17194
  return connectWithSiwe;
@@ -16260,7 +17407,7 @@ const ConnectWithInjector = ({ forceState }) => {
16260
17407
  const { disconnect } = useDisconnect();
16261
17408
  const connectWithSiwe = useConnectWithSiwe();
16262
17409
  const props = useRouteProps(routes.CONNECT);
16263
- const { user } = useUser();
17410
+ const { linkedAccounts } = useUser();
16264
17411
  const onConnect = useCallback(() => {
16265
17412
  setStatus(states$3.CONNECTED);
16266
17413
  setTimeout(() => {
@@ -16335,7 +17482,7 @@ const ConnectWithInjector = ({ forceState }) => {
16335
17482
  });
16336
17483
  return;
16337
17484
  }
16338
- const userWallets = user === null || user === void 0 ? void 0 : user.linkedAccounts.filter((acc) => {
17485
+ const userWallets = linkedAccounts === null || linkedAccounts === void 0 ? void 0 : linkedAccounts.filter((acc) => {
16339
17486
  var _a, _b;
16340
17487
  return acc.walletClientType === ((_a = wallet.connector) === null || _a === void 0 ? void 0 : _a.name.toLowerCase()) ||
16341
17488
  acc.walletClientType === ((_b = wallet.connector) === null || _b === void 0 ? void 0 : _b.id);
@@ -16343,7 +17490,7 @@ const ConnectWithInjector = ({ forceState }) => {
16343
17490
  // If already has linked account, don't link again
16344
17491
  if (userWallets && userWallets.length > 0) {
16345
17492
  wallet.connector.getAccounts().then((acc) => {
16346
- if (acc.some((v) => userWallets.some((w) => w.address === v))) {
17493
+ if (acc.some((v) => userWallets.some((w) => w.accountId === v))) {
16347
17494
  onConnect();
16348
17495
  return;
16349
17496
  }
@@ -16353,15 +17500,15 @@ const ConnectWithInjector = ({ forceState }) => {
16353
17500
  connectWithSiwe({
16354
17501
  // connectorType: wallet.connector.id,
16355
17502
  // walletClientType: wallet.connector.name.toLowerCase(),
16356
- onError: (error, errorType) => {
17503
+ onError: (error, _errorType) => {
16357
17504
  logger.error(error);
16358
17505
  disconnect();
16359
- if (errorType === OpenfortErrorType$1.AUTHENTICATION_ERROR) {
16360
- setStatus(states$3.DUPLICATED);
16361
- }
16362
- else {
16363
- setStatus(states$3.FAILED);
16364
- }
17506
+ // TODO: TMP FIX: Handle siwe error properly
17507
+ // if (errorType) {
17508
+ // setStatus(states.DUPLICATED)
17509
+ // } else {
17510
+ setStatus(states$3.FAILED);
17511
+ // }
16365
17512
  },
16366
17513
  onConnect: () => {
16367
17514
  onConnect();
@@ -16492,7 +17639,7 @@ const ConnectWithOAuth = () => {
16492
17639
  (async () => {
16493
17640
  if (connector.type !== 'oauth')
16494
17641
  throw new Error('Invalid connector type');
16495
- const url = new URL(window.location.href);
17642
+ const url = new URL(window.location.href.replace('?access_token=', '&access_token=')); // handle both ? and & cases
16496
17643
  const hasProvider = !!url.searchParams.get('openfortAuthProviderUI');
16497
17644
  const provider = connector.id;
16498
17645
  switch (status) {
@@ -16503,21 +17650,34 @@ const ConnectWithOAuth = () => {
16503
17650
  setTimeout(() => setStatus(states$2.REDIRECT), 150); // UX: wait a bit before redirecting
16504
17651
  break;
16505
17652
  case states$2.CONNECTING: {
16506
- const player = url.searchParams.get('player_id');
16507
- const accessToken = url.searchParams.get('access_token');
16508
- const refreshToken = url.searchParams.get('refresh_token');
16509
- ['openfortAuthProviderUI', 'refresh_token', 'access_token', 'player_id'].forEach((key) => {
17653
+ const userId = url.searchParams.get('user_id');
17654
+ const token = url.searchParams.get('access_token');
17655
+ const error = url.searchParams.get('error');
17656
+ ['openfortAuthProviderUI', 'access_token', 'user_id', 'error'].forEach((key) => {
16510
17657
  url.searchParams.delete(key);
16511
17658
  });
16512
17659
  window.history.replaceState({}, document.title, url.toString());
16513
- if (!player || !accessToken || !refreshToken) {
16514
- logger.error(`Missing player id or access token or refresh token: player=${player}, accessToken=${accessToken ? `${accessToken.substring(0, 10)}...` : accessToken}, refreshToken=${refreshToken}`);
17660
+ if (!userId || !token || error) {
17661
+ logger.error(`Missing user id or access token: userId=${userId}, accessToken=${token ? `${token.substring(0, 10)}...` : token}`);
17662
+ setStatus(states$2.ERROR);
17663
+ if (error) {
17664
+ switch (error) {
17665
+ case "email_doesn't_match":
17666
+ setDescription('The email associated with this OAuth provider does not match your account email.');
17667
+ break;
17668
+ default:
17669
+ setDescription('There was an error during authentication. Please try again.');
17670
+ }
17671
+ }
17672
+ else {
17673
+ setDescription('There was an error during authentication. Please try again.');
17674
+ }
17675
+ triggerResize();
16515
17676
  return;
16516
17677
  }
16517
17678
  client.auth.storeCredentials({
16518
- player,
16519
- accessToken,
16520
- refreshToken,
17679
+ token,
17680
+ userId,
16521
17681
  });
16522
17682
  setRoute(routes.LOADING);
16523
17683
  break;
@@ -16537,26 +17697,19 @@ const ConnectWithOAuth = () => {
16537
17697
  return;
16538
17698
  }
16539
17699
  const linkResponse = await client.auth.initLinkOAuth({
16540
- authToken,
16541
17700
  provider,
16542
- options: {
16543
- redirectTo: cleanURL,
16544
- queryParams,
16545
- },
17701
+ redirectTo: `${cleanURL}?${new URLSearchParams(queryParams).toString()}`,
16546
17702
  });
16547
17703
  logger.log(linkResponse);
16548
- window.location.href = linkResponse.url;
17704
+ window.location.href = linkResponse;
16549
17705
  }
16550
17706
  else {
16551
17707
  const r = await client.auth.initOAuth({
16552
17708
  provider,
16553
- options: {
16554
- redirectTo: cleanURL,
16555
- queryParams,
16556
- },
17709
+ redirectTo: `${cleanURL}?${new URLSearchParams(queryParams).toString()}`,
16557
17710
  });
16558
17711
  logger.log(r);
16559
- window.location.href = r.url;
17712
+ window.location.href = r;
16560
17713
  }
16561
17714
  }
16562
17715
  catch (e) {
@@ -16835,6 +17988,8 @@ const ConnectModal = ({ mode = 'auto', theme = 'auto', customTheme = customTheme
16835
17988
  createGuestUser: jsx(CreateGuestUserPage, {}),
16836
17989
  socialProviders: jsx(SocialProviders, {}),
16837
17990
  emailLogin: jsx(EmailLogin, {}),
17991
+ emailOtp: jsx(EmailOTP, {}),
17992
+ phoneOtp: jsx(PhoneOTP, {}),
16838
17993
  forgotPassword: jsx(ForgotPassword, {}),
16839
17994
  emailVerification: jsx(EmailVerification, {}),
16840
17995
  linkEmail: jsx(LinkEmail, {}),
@@ -16850,6 +18005,8 @@ const ConnectModal = ({ mode = 'auto', theme = 'auto', customTheme = customTheme
16850
18005
  profile: jsx(Profile, {}),
16851
18006
  switchNetworks: jsx(SwitchNetworks, {}),
16852
18007
  linkedProviders: jsx(LinkedProviders, {}),
18008
+ linkedProvider: jsx(LinkedProvider$1, {}),
18009
+ removeLinkedProvider: jsx(RemoveLinkedProvider, {}),
16853
18010
  connectWithMobile: jsx(ConnectWithMobile, {}),
16854
18011
  noAssetsAvailable: jsx(NoAssetsAvailable, {}),
16855
18012
  assetInventory: jsx(AssetInventory, {}),
@@ -16870,11 +18027,11 @@ const ConnectModal = ({ mode = 'auto', theme = 'auto', customTheme = customTheme
16870
18027
  }
16871
18028
  // if auth redirect
16872
18029
  useEffect(() => {
16873
- const url = new URL(window.location.href);
18030
+ const url = new URL(window.location.href.replace('?access_token=', '&access_token=')); // handle both ? and & cases
16874
18031
  const provider = url.searchParams.get('openfortAuthProviderUI');
16875
18032
  const emailVerification = url.searchParams.get('openfortEmailVerificationUI');
16876
18033
  const forgotPassword = url.searchParams.get('openfortForgotPasswordUI');
16877
- logger.log('Checking for search parameters', url);
18034
+ logger.log('Checking for search parameters', { url, provider, emailVerification, forgotPassword });
16878
18035
  if (emailVerification) {
16879
18036
  context.setOpen(true);
16880
18037
  context.setRoute(routes.EMAIL_VERIFICATION);
@@ -16996,12 +18153,13 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
16996
18153
  }
16997
18154
  const debugModeOptions = useMemo(() => {
16998
18155
  const getDebugMode = () => {
16999
- var _a, _b, _c;
18156
+ var _a, _b, _c, _d;
17000
18157
  if (typeof debugMode === 'undefined') {
17001
18158
  return {
17002
18159
  shieldDebugMode: false,
17003
18160
  openfortCoreDebugMode: false,
17004
18161
  openfortReactDebugMode: false,
18162
+ debugRoutes: false,
17005
18163
  };
17006
18164
  }
17007
18165
  else if (typeof debugMode === 'boolean') {
@@ -17009,6 +18167,7 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
17009
18167
  shieldDebugMode: debugMode,
17010
18168
  openfortCoreDebugMode: debugMode,
17011
18169
  openfortReactDebugMode: debugMode,
18170
+ debugRoutes: false,
17012
18171
  };
17013
18172
  }
17014
18173
  else {
@@ -17016,6 +18175,7 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
17016
18175
  shieldDebugMode: (_a = debugMode.shieldDebugMode) !== null && _a !== void 0 ? _a : false,
17017
18176
  openfortCoreDebugMode: (_b = debugMode.openfortCoreDebugMode) !== null && _b !== void 0 ? _b : false,
17018
18177
  openfortReactDebugMode: (_c = debugMode.openfortReactDebugMode) !== null && _c !== void 0 ? _c : false,
18178
+ debugRoutes: (_d = debugMode.debugRoutes) !== null && _d !== void 0 ? _d : false,
17019
18179
  };
17020
18180
  }
17021
18181
  };
@@ -17092,6 +18252,7 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
17092
18252
  const [errorMessage, setErrorMessage] = useState('');
17093
18253
  const [resize, onResize] = useState(0);
17094
18254
  const [emailInput, setEmailInput] = useState('');
18255
+ const [phoneInput, setPhoneInput] = useState('');
17095
18256
  const [sendForm, setSendForm] = useState(defaultSendFormState);
17096
18257
  const [buyForm, setBuyForm] = useState(defaultBuyFormState);
17097
18258
  const [headerLeftSlot, setHeaderLeftSlot] = useState(null);
@@ -17185,6 +18346,8 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
17185
18346
  debugMode: debugModeOptions,
17186
18347
  emailInput,
17187
18348
  setEmailInput,
18349
+ phoneInput,
18350
+ setPhoneInput,
17188
18351
  resize,
17189
18352
  triggerResize,
17190
18353
  publishableKey,
@@ -17211,7 +18374,19 @@ const OpenfortProvider = ({ children, uiConfig, onConnect, onDisconnect, debugMo
17211
18374
  debug: debugModeOptions.openfortCoreDebugMode,
17212
18375
  overrides,
17213
18376
  thirdPartyAuth,
17214
- }, onConnect: onConnect, onDisconnect: onDisconnect, children: [children, jsx(ConnectModal, { lang: ckLang, theme: ckTheme, mode: (_e = safeUiConfig.mode) !== null && _e !== void 0 ? _e : ckMode, customTheme: ckCustomTheme })] }) }));
18377
+ }, onConnect: onConnect, onDisconnect: onDisconnect, children: [debugModeOptions.debugRoutes && (jsx("pre", { style: {
18378
+ position: 'absolute',
18379
+ top: 0,
18380
+ left: 0,
18381
+ fontSize: '14px',
18382
+ color: 'gray',
18383
+ background: 'white',
18384
+ zIndex: 9999,
18385
+ }, children: JSON.stringify(routeHistory.map((item) => Object.fromEntries(Object.entries(item).map(([key, value]) => [
18386
+ key,
18387
+ typeof value === 'object' && value !== null ? '[object]' : value,
18388
+ ]))), null, 2) // For debugging purposes
18389
+ })), children, jsx(ConnectModal, { lang: ckLang, theme: ckTheme, mode: (_e = safeUiConfig.mode) !== null && _e !== void 0 ? _e : ckMode, customTheme: ckCustomTheme })] }) }));
17215
18390
  };
17216
18391
 
17217
18392
  /**
@@ -17295,16 +18470,15 @@ const useOAuth = (hookOptions = {}) => {
17295
18470
  });
17296
18471
  const { isOpen } = useUI();
17297
18472
  const { tryUseWallet } = useConnectToWalletPostAuth();
17298
- const storeCredentials = useCallback(async ({ player, accessToken, refreshToken, ...options }) => {
18473
+ const storeCredentials = useCallback(async ({ userId, token, ...options }) => {
17299
18474
  var _a, _b;
17300
18475
  setStatus({
17301
18476
  status: 'loading',
17302
18477
  });
17303
18478
  try {
17304
18479
  await client.auth.storeCredentials({
17305
- player,
17306
- accessToken,
17307
- refreshToken,
18480
+ userId,
18481
+ token,
17308
18482
  });
17309
18483
  setStatus({
17310
18484
  status: 'success',
@@ -17321,7 +18495,7 @@ const useOAuth = (hookOptions = {}) => {
17321
18495
  });
17322
18496
  }
17323
18497
  catch (e) {
17324
- const error = new OpenfortError('Failed to store credentials', OpenfortErrorType.AUTHENTICATION_ERROR, {
18498
+ const error = new OpenfortError('Failed to store credentials', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
17325
18499
  error: e,
17326
18500
  });
17327
18501
  setStatus({
@@ -17344,13 +18518,11 @@ const useOAuth = (hookOptions = {}) => {
17344
18518
  });
17345
18519
  await client.auth.initOAuth({
17346
18520
  provider: authProvider,
17347
- options: {
17348
- redirectTo: buildCallbackUrl({
17349
- provider: authProvider,
17350
- callbackUrl: (_a = hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.redirectTo) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.redirectTo,
17351
- isOpen,
17352
- }),
17353
- },
18521
+ redirectTo: buildCallbackUrl({
18522
+ provider: authProvider,
18523
+ callbackUrl: (_a = hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.redirectTo) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.redirectTo,
18524
+ isOpen,
18525
+ }),
17354
18526
  });
17355
18527
  return onSuccess({
17356
18528
  data: {},
@@ -17359,7 +18531,7 @@ const useOAuth = (hookOptions = {}) => {
17359
18531
  });
17360
18532
  }
17361
18533
  catch (e) {
17362
- const error = new OpenfortError('Failed to login with OAuth', OpenfortErrorType.AUTHENTICATION_ERROR, {
18534
+ const error = new OpenfortError('Failed to login with OAuth', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
17363
18535
  error: e,
17364
18536
  });
17365
18537
  setStatus({
@@ -17382,18 +18554,15 @@ const useOAuth = (hookOptions = {}) => {
17382
18554
  });
17383
18555
  const authToken = await client.getAccessToken();
17384
18556
  if (!authToken) {
17385
- throw new OpenfortError('No auth token found', OpenfortErrorType.AUTHENTICATION_ERROR);
18557
+ throw new OpenfortError('No auth token found', OpenfortReactErrorType.AUTHENTICATION_ERROR);
17386
18558
  }
17387
18559
  await client.auth.initLinkOAuth({
17388
- authToken,
17389
18560
  provider: authProvider,
17390
- options: {
17391
- redirectTo: buildCallbackUrl({
17392
- provider: authProvider,
17393
- callbackUrl: (_a = options === null || options === void 0 ? void 0 : options.redirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.redirectTo,
17394
- isOpen,
17395
- }),
17396
- },
18561
+ redirectTo: buildCallbackUrl({
18562
+ provider: authProvider,
18563
+ callbackUrl: (_a = options === null || options === void 0 ? void 0 : options.redirectTo) !== null && _a !== void 0 ? _a : hookOptions === null || hookOptions === void 0 ? void 0 : hookOptions.redirectTo,
18564
+ isOpen,
18565
+ }),
17397
18566
  });
17398
18567
  return onSuccess({
17399
18568
  data: {},
@@ -17402,7 +18571,9 @@ const useOAuth = (hookOptions = {}) => {
17402
18571
  });
17403
18572
  }
17404
18573
  catch (e) {
17405
- const error = new OpenfortError('Failed to link OAuth', OpenfortErrorType.AUTHENTICATION_ERROR, { error: e });
18574
+ const error = new OpenfortError('Failed to link OAuth', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
18575
+ error: e,
18576
+ });
17406
18577
  setStatus({
17407
18578
  status: 'error',
17408
18579
  error,
@@ -17474,13 +18645,11 @@ const useOAuth = (hookOptions = {}) => {
17474
18645
  * state: 'verification-token',
17475
18646
  * });
17476
18647
  * };
17477
- *
17478
- * // Manually store credentials (if needed)
17479
- * const handleManualStore = async () => {
18648
+ * // Manually trigger storing credentials (if needed)
18649
+ * const handleManualStoreCredentials = async () => {
17480
18650
  * await authCallback.storeCredentials({
17481
- * player: 'player-id',
17482
- * accessToken: 'access-token',
17483
- * refreshToken: 'refresh-token',
18651
+ * userId: 'player-id',
18652
+ * token: 'access-token',
17484
18653
  * });
17485
18654
  * };
17486
18655
  * ```
@@ -17513,7 +18682,7 @@ const useAuthCallback = ({ enabled = true, // Automatically handle OAuth and ema
17513
18682
  onError({
17514
18683
  hookOptions,
17515
18684
  options: {},
17516
- error: new OpenfortError('No state or email found in URL', OpenfortErrorType.AUTHENTICATION_ERROR),
18685
+ error: new OpenfortError('No state or email found in URL', OpenfortReactErrorType.AUTHENTICATION_ERROR),
17517
18686
  });
17518
18687
  return;
17519
18688
  }
@@ -17547,30 +18716,28 @@ const useAuthCallback = ({ enabled = true, // Automatically handle OAuth and ema
17547
18716
  removeParams();
17548
18717
  }
17549
18718
  else {
17550
- const player = url.searchParams.get('player_id');
17551
- const accessToken = url.searchParams.get('access_token');
17552
- const refreshToken = url.searchParams.get('refresh_token');
17553
- if (!player || !accessToken || !refreshToken) {
17554
- logger.error(`Missing player id or access token or refresh token`, {
17555
- player,
17556
- accessToken: accessToken ? `${accessToken.substring(0, 10)}...` : accessToken,
17557
- refreshToken,
18719
+ const userId = url.searchParams.get('user_id');
18720
+ const token = url.searchParams.get('access_token');
18721
+ if (!userId || !token) {
18722
+ logger.error(`Missing user id or access token`, {
18723
+ userId,
18724
+ token: token ? `${token.substring(0, 10)}...` : token,
17558
18725
  fixedUrl,
17559
18726
  });
17560
18727
  onError({
17561
18728
  hookOptions,
17562
18729
  options: {},
17563
- error: new OpenfortError('Missing player id or access token or refresh token', OpenfortErrorType.AUTHENTICATION_ERROR),
18730
+ error: new OpenfortError('Missing player id or access token or refresh token', OpenfortReactErrorType.AUTHENTICATION_ERROR),
17564
18731
  });
17565
18732
  return;
17566
18733
  }
17567
18734
  const removeParams = () => {
17568
- ['openfortAuthProvider', 'refresh_token', 'access_token', 'player_id'].forEach((key) => {
18735
+ ['openfortAuthProvider', 'access_token', 'user_id'].forEach((key) => {
17569
18736
  url.searchParams.delete(key);
17570
18737
  });
17571
18738
  window.history.replaceState({}, document.title, url.toString());
17572
18739
  };
17573
- logger.log('callback', { player, accessToken, refreshToken });
18740
+ logger.log('callback', { userId });
17574
18741
  const options = {
17575
18742
  onSuccess: (data) => {
17576
18743
  var _a;
@@ -17589,7 +18756,7 @@ const useAuthCallback = ({ enabled = true, // Automatically handle OAuth and ema
17589
18756
  onError: hookOptions.onError,
17590
18757
  throwOnError: hookOptions.throwOnError,
17591
18758
  };
17592
- await storeCredentials({ player, accessToken, refreshToken, ...options });
18759
+ await storeCredentials({ userId, token, ...options });
17593
18760
  removeParams();
17594
18761
  }
17595
18762
  })();
@@ -17630,7 +18797,7 @@ const useWalletAuth = (hookOptions = {}) => {
17630
18797
  const { connectAsync } = useConnect({
17631
18798
  mutation: {
17632
18799
  onError: (e) => {
17633
- const error = new OpenfortError('Failed to connect with wallet', OpenfortErrorType.AUTHENTICATION_ERROR, {
18800
+ const error = new OpenfortError('Failed to connect with wallet', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
17634
18801
  error: e,
17635
18802
  });
17636
18803
  handleError(error);
@@ -17649,7 +18816,7 @@ const useWalletAuth = (hookOptions = {}) => {
17649
18816
  onError: (e) => {
17650
18817
  logger.log('Error connecting with SIWE', e);
17651
18818
  disconnect();
17652
- const error = new OpenfortError('Failed to connect with siwe', OpenfortErrorType.AUTHENTICATION_ERROR, {
18819
+ const error = new OpenfortError('Failed to connect with siwe', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
17653
18820
  error: e,
17654
18821
  });
17655
18822
  handleError(error);
@@ -17752,7 +18919,7 @@ const useWalletAuth = (hookOptions = {}) => {
17752
18919
  }
17753
18920
  if (!connector) {
17754
18921
  logger.log('Connector not found', connector);
17755
- return handleError(new OpenfortError('Connector not found', OpenfortErrorType.AUTHENTICATION_ERROR));
18922
+ return handleError(new OpenfortError('Connector not found', OpenfortReactErrorType.AUTHENTICATION_ERROR));
17756
18923
  }
17757
18924
  setWalletConnectingTo(connector.id);
17758
18925
  const hasDisconnected = new Promise((resolve) => {
@@ -17762,7 +18929,7 @@ const useWalletAuth = (hookOptions = {}) => {
17762
18929
  },
17763
18930
  onError: (e) => {
17764
18931
  logger.error('Error disconnecting', e);
17765
- const error = new OpenfortError('Failed to disconnect', OpenfortErrorType.AUTHENTICATION_ERROR, {
18932
+ const error = new OpenfortError('Failed to disconnect', OpenfortReactErrorType.AUTHENTICATION_ERROR, {
17766
18933
  error: e,
17767
18934
  });
17768
18935
  handleError(error);
@@ -17779,7 +18946,7 @@ const useWalletAuth = (hookOptions = {}) => {
17779
18946
  }
17780
18947
  catch (error) {
17781
18948
  logger.error('Error connecting', error);
17782
- handleError(new OpenfortError('Failed to connect', OpenfortErrorType.AUTHENTICATION_ERROR, { error }));
18949
+ handleError(new OpenfortError('Failed to connect', OpenfortReactErrorType.AUTHENTICATION_ERROR, { error }));
17783
18950
  }
17784
18951
  }, [siwe, disconnect, updateUser, availableWallets, setStatus, hookOptions]);
17785
18952
  return {
@@ -17826,11 +18993,11 @@ function use7702Authorization() {
17826
18993
  arrayifyMessage: false,
17827
18994
  }) => {
17828
18995
  if (!client) {
17829
- throw new OpenfortError('Openfort client is not initialized.', OpenfortErrorType.CONFIGURATION_ERROR);
18996
+ throw new OpenfortError('Openfort client is not initialized.', OpenfortReactErrorType.CONFIGURATION_ERROR);
17830
18997
  }
17831
18998
  const authorization = parameters;
17832
18999
  if (!authorization.contractAddress) {
17833
- throw new OpenfortError('Authorization is missing the contract address to sign.', OpenfortErrorType.VALIDATION_ERROR);
19000
+ throw new OpenfortError('Authorization is missing the contract address to sign.', OpenfortReactErrorType.VALIDATION_ERROR);
17834
19001
  }
17835
19002
  const hash = hashAuthorization(authorization);
17836
19003
  try {
@@ -17850,7 +19017,7 @@ function use7702Authorization() {
17850
19017
  };
17851
19018
  }
17852
19019
  catch (error) {
17853
- throw new OpenfortError('Failed to sign authorization.', OpenfortErrorType.WALLET_ERROR, { error });
19020
+ throw new OpenfortError('Failed to sign authorization.', OpenfortReactErrorType.WALLET_ERROR, { error });
17854
19021
  }
17855
19022
  }, [client]);
17856
19023
  return { signAuthorization };
@@ -17950,7 +19117,7 @@ const useGrantPermissions = (hookOptions = {}) => {
17950
19117
  try {
17951
19118
  logger.log('Granting permissions with request:', request);
17952
19119
  if (!walletClient) {
17953
- throw new OpenfortError('Wallet client not available', OpenfortErrorType.WALLET_ERROR);
19120
+ throw new OpenfortError('Wallet client not available', OpenfortReactErrorType.WALLET_ERROR);
17954
19121
  }
17955
19122
  setStatus({
17956
19123
  status: 'loading',
@@ -17958,7 +19125,7 @@ const useGrantPermissions = (hookOptions = {}) => {
17958
19125
  // Get the current chain configuration
17959
19126
  const chain = chains.find((c) => c.id === chainId);
17960
19127
  if (!chain) {
17961
- throw new OpenfortError('No chain configured', OpenfortErrorType.CONFIGURATION_ERROR);
19128
+ throw new OpenfortError('No chain configured', OpenfortReactErrorType.CONFIGURATION_ERROR);
17962
19129
  }
17963
19130
  // Get the account address
17964
19131
  const [account] = await walletClient.getAddresses();
@@ -17980,7 +19147,7 @@ const useGrantPermissions = (hookOptions = {}) => {
17980
19147
  });
17981
19148
  }
17982
19149
  catch (error) {
17983
- const openfortError = new OpenfortError('Failed to grant permissions', OpenfortErrorType.WALLET_ERROR, {
19150
+ const openfortError = new OpenfortError('Failed to grant permissions', OpenfortReactErrorType.WALLET_ERROR, {
17984
19151
  error,
17985
19152
  });
17986
19153
  setStatus({
@@ -18053,7 +19220,7 @@ const useRevokePermissions = (hookOptions = {}) => {
18053
19220
  const revokePermissions = useCallback(async ({ sessionKey }, options = {}) => {
18054
19221
  try {
18055
19222
  if (!walletClient) {
18056
- throw new OpenfortError('Wallet client not available', OpenfortErrorType.WALLET_ERROR);
19223
+ throw new OpenfortError('Wallet client not available', OpenfortReactErrorType.WALLET_ERROR);
18057
19224
  }
18058
19225
  logger.log('Revoking permissions for session key:', sessionKey);
18059
19226
  setStatus({
@@ -18062,7 +19229,7 @@ const useRevokePermissions = (hookOptions = {}) => {
18062
19229
  // Get the current chain configuration
18063
19230
  const chain = chains.find((c) => c.id === chainId);
18064
19231
  if (!chain) {
18065
- throw new OpenfortError('No chain configured', OpenfortErrorType.CONFIGURATION_ERROR);
19232
+ throw new OpenfortError('No chain configured', OpenfortReactErrorType.CONFIGURATION_ERROR);
18066
19233
  }
18067
19234
  // Get the account address
18068
19235
  const revokePermissionsResult = await walletClient.request({
@@ -18086,7 +19253,7 @@ const useRevokePermissions = (hookOptions = {}) => {
18086
19253
  });
18087
19254
  }
18088
19255
  catch (error) {
18089
- const openfortError = new OpenfortError('Failed to revoke permissions', OpenfortErrorType.WALLET_ERROR, {
19256
+ const openfortError = new OpenfortError('Failed to revoke permissions', OpenfortReactErrorType.WALLET_ERROR, {
18090
19257
  error,
18091
19258
  });
18092
19259
  setStatus({
@@ -18137,5 +19304,5 @@ const wallets = Object.keys(walletConfigs).reduce((acc, key) => {
18137
19304
  return acc;
18138
19305
  }, {});
18139
19306
 
18140
- export { UIAuthProvider as AuthProvider, Avatar, Chain as ChainIcon, LinkWalletOnSignUpOption, OPENFORT_VERSION, OpenfortButton, OpenfortError, OpenfortErrorType, OpenfortProvider, embeddedWalletId, defaultConfig as getDefaultConfig, defaultConnectors as getDefaultConnectors, use7702Authorization, useAuthCallback, useChainIsSupported, useChains, useConnectWithSiwe, useEmailAuth, useGrantPermissions, useGuestAuth, useOAuth, useOpenfortCore as useOpenfort, useRevokePermissions, useSignOut, useUI, useUser, useWalletAssets, useWalletAuth, useWallets, wallets };
19307
+ export { UIAuthProvider as AuthProvider, Avatar, Chain as ChainIcon, LinkWalletOnSignUpOption, OPENFORT_VERSION, OpenfortButton, OpenfortError, OpenfortReactErrorType as OpenfortErrorType, OpenfortProvider, embeddedWalletId, defaultConfig as getDefaultConfig, defaultConnectors as getDefaultConnectors, use7702Authorization, useAuthCallback, useChainIsSupported, useChains, useConnectWithSiwe, useEmailAuth, useGrantPermissions, useGuestAuth, useOAuth, useOpenfortCore as useOpenfort, useRevokePermissions, useSignOut, useUI, useUser, useWalletAssets, useWalletAuth, useWallets, wallets };
18141
19308
  //# sourceMappingURL=index.es.js.map