@openfort/react 1.0.7 → 1.0.8

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.
@@ -1,4 +1,4 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
 
3
3
  const SendIcon = ({ ...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: "M5 19L19 5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: "M9 5H19V15", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" })] }));
4
4
  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" })] }));
@@ -1,10 +1,9 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { ChainTypeEnum, OAuthProvider } from '@openfort/openfort-js';
3
- import { useMemo, useRef, useEffect } from 'react';
3
+ import { lazy, Suspense, useMemo, useRef, useEffect } from 'react';
4
4
  import { useConnectionStrategy } from '../../core/ConnectionStrategyContext.js';
5
5
  import { useOpenfortCore } from '../../openfort/useOpenfort.js';
6
6
  import { logger } from '../../utils/logger.js';
7
- import SwitchNetworks from '../../wagmi/components/SwitchNetworks/index.js';
8
7
  import Modal from '../Common/Modal/index.js';
9
8
  import { ConnectKitThemeProvider } from '../ConnectKitThemeProvider/ConnectKitThemeProvider.js';
10
9
  import { routes } from '../Openfort/types.js';
@@ -49,6 +48,7 @@ import SocialProviders from '../Pages/SocialProviders/index.js';
49
48
  import ConnectUsing from './ConnectUsing.js';
50
49
  import ConnectWithMobile from './ConnectWithMobile.js';
51
50
 
51
+ const LazySwitchNetworks = lazy(() => import('../../wagmi/components/SwitchNetworks/index.js'));
52
52
  function buildSharedPages() {
53
53
  return {
54
54
  onboarding: jsx(Introduction, {}),
@@ -99,7 +99,7 @@ const CHAIN_PREFIXED_PAGES = {
99
99
  'eth:connected': jsx(Connected, {}),
100
100
  'eth:createWallet': jsx(CreateWallet, {}),
101
101
  'eth:recoverWallet': jsx(RecoverPage, {}),
102
- 'eth:switchNetworks': jsx(SwitchNetworks, {}),
102
+ 'eth:switchNetworks': (jsx(Suspense, { fallback: null, children: jsx(LazySwitchNetworks, {}) })),
103
103
  'eth:send': jsx(Send, {}),
104
104
  'eth:receive': jsx(Receive, {}),
105
105
  'eth:buy': jsx(Buy, {}),
@@ -1,20 +1,21 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { ChainTypeEnum } from '@openfort/openfort-js';
3
3
  import { AnimatePresence, motion } from 'framer-motion';
4
- import { useEffect, useMemo, useState } from 'react';
4
+ import { lazy, useEffect, useMemo, useState, Suspense } from 'react';
5
5
  import { formatUnits } from 'viem';
6
6
  import { UserRoundIcon, SendIcon, ReceiveIcon, BuyIcon } from '../../../assets/icons.js';
7
7
  import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
8
8
  import { useEthereumWalletAssets } from '../../../ethereum/hooks/useEthereumWalletAssets.js';
9
+ import { useEthereumBridge } from '../../../ethereum/OpenfortEthereumBridgeContext.js';
9
10
  import useLocales from '../../../hooks/useLocales.js';
10
11
  import { useResolvedIdentity } from '../../../hooks/useResolvedIdentity.js';
11
12
  import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
12
13
  import { nFormatter } from '../../../utils/index.js';
13
14
  import { logger } from '../../../utils/logger.js';
14
- import ChainSelector from '../../../wagmi/components/ChainSelect/index.js';
15
15
  import Avatar from '../../Common/Avatar/index.js';
16
16
  import Button from '../../Common/Button/index.js';
17
17
  import { TextLinkButton } from '../../Common/Button/styles.js';
18
+ import Chain from '../../Common/Chain/index.js';
18
19
  import { CopyText } from '../../Common/CopyToClipboard/CopyText.js';
19
20
  import { ModalBody } from '../../Common/Modal/styles.js';
20
21
  import { useThemeContext } from '../../ConnectKitThemeProvider/ConnectKitThemeProvider.js';
@@ -26,6 +27,7 @@ import { ConnectedPageLayout } from './ConnectedPageLayout.js';
26
27
  import { LinkedProvidersToggle, Balance, Unsupported, ChainSelectorContainer, ActionButton } from './styles.js';
27
28
  import { truncateEthAddress } from '../../../utils/format.js';
28
29
 
30
+ const LazyChainSelector = lazy(() => import('../../../wagmi/components/ChainSelect/index.js'));
29
31
  function getFirstBalanceAsset(assets) {
30
32
  return assets === null || assets === void 0 ? void 0 : assets.find((a) => a.balance && a.balance > BigInt(0));
31
33
  }
@@ -34,6 +36,7 @@ const EthereumConnected = () => {
34
36
  const context = useOpenfort();
35
37
  const { setHeaderLeftSlot, setRoute, chains } = context;
36
38
  const themeContext = useThemeContext();
39
+ const bridge = useEthereumBridge();
37
40
  const wallet = useEthereumEmbeddedWallet();
38
41
  const { embeddedAccounts } = useOpenfortCore();
39
42
  const hasEthereumWallets = ((_a = embeddedAccounts === null || embeddedAccounts === void 0 ? void 0 : embeddedAccounts.filter((a) => a.chainType === ChainTypeEnum.EVM)) !== null && _a !== void 0 ? _a : []).length > 0;
@@ -117,8 +120,8 @@ const EthereumConnected = () => {
117
120
  }
118
121
  setRoute(routes.ASSET_INVENTORY);
119
122
  }, children: jsxs(Balance, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, children: ["$", nFormatter(totalBalanceUsd)] }, `chain-${chain === null || chain === void 0 ? void 0 : chain.id}`) })) : null;
120
- const noWalletFallback = hasEthereumWallets ? (jsx(Button, { onClick: () => context.setRoute(routes.LOAD_WALLETS), children: "Manage wallets" })) : (jsx(Button, { onClick: () => context.setRoute({ route: routes.CONNECTORS, connectType: 'link' }), icon: jsx(Unsupported, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, children: jsxs("svg", { width: "130", height: "120", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("title", { children: "Unsupported wallet icon" }), jsx("path", { d: "M2.61317 11.2501H9.46246C10.6009 11.2501 11.3256 10.3506 11.3256 9.3549C11.3256 9.05145 11.255 8.73244 11.0881 8.43303L7.65903 2.14708C7.659 2.14702 7.65897 2.14696 7.65893 2.1469C7.65889 2.14682 7.65884 2.14673 7.65879 2.14664C7.31045 1.50746 6.6741 1.17871 6.04 1.17871C5.41478 1.17871 4.763 1.50043 4.41518 2.14968L0.993416 8.43476C0.828865 8.72426 0.75 9.04297 0.75 9.3549C0.75 10.3506 1.47471 11.2501 2.61317 11.2501Z", fill: "currentColor", stroke: "var(--ck-body-background, #fff)", strokeWidth: "1.5" }), jsx("path", { d: "M6.03258 7.43916C5.77502 7.43916 5.63096 7.29153 5.62223 7.02311L5.55675 4.96973C5.54802 4.69684 5.74446 4.5 6.02821 4.5C6.3076 4.5 6.51277 4.70131 6.50404 4.9742L6.43856 7.01864C6.42546 7.29153 6.2814 7.43916 6.03258 7.43916ZM6.03258 9.11676C5.7401 9.11676 5.5 8.9065 5.5 8.60677C5.5 8.30704 5.7401 8.09678 6.03258 8.09678C6.32506 8.09678 6.56515 8.30256 6.56515 8.60677C6.56515 8.91097 6.32069 9.11676 6.03258 9.11676Z", fill: "white" })] }) }), children: "Connect wallet" }));
121
- return (jsx(PageContent, { onBack: null, header: locales.profileScreen_heading, children: jsx(ConnectedPageLayout, { address: address !== null && address !== void 0 ? address : '', displayName: jsx(CopyText, { value: address !== null && address !== void 0 ? address : '', children: ensName !== null && ensName !== void 0 ? ensName : truncateEthAddress(address !== null && address !== void 0 ? address : '', separator) }), avatar: address ? jsx(Avatar, { address: address }) : jsx("span", {}), beforeAvatar: jsx(ChainSelectorContainer, { initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.2 }, children: jsx(ChainSelector, {}) }, chainId !== null && chainId !== void 0 ? chainId : 'loading'), balance: balanceNode, actions: jsxs(Fragment, { children: [jsx(ActionButton, { icon: jsx(SendIcon, {}), onClick: () => {
123
+ const noWalletFallback = hasEthereumWallets ? (jsx(Button, { onClick: () => context.setRoute(routes.SELECT_WALLET_TO_RECOVER), children: "Manage wallets" })) : (jsx(Button, { onClick: () => context.setRoute({ route: routes.CONNECTORS, connectType: 'link' }), icon: jsx(Unsupported, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, children: jsxs("svg", { width: "130", height: "120", viewBox: "0 0 13 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("title", { children: "Unsupported wallet icon" }), jsx("path", { d: "M2.61317 11.2501H9.46246C10.6009 11.2501 11.3256 10.3506 11.3256 9.3549C11.3256 9.05145 11.255 8.73244 11.0881 8.43303L7.65903 2.14708C7.659 2.14702 7.65897 2.14696 7.65893 2.1469C7.65889 2.14682 7.65884 2.14673 7.65879 2.14664C7.31045 1.50746 6.6741 1.17871 6.04 1.17871C5.41478 1.17871 4.763 1.50043 4.41518 2.14968L0.993416 8.43476C0.828865 8.72426 0.75 9.04297 0.75 9.3549C0.75 10.3506 1.47471 11.2501 2.61317 11.2501Z", fill: "currentColor", stroke: "var(--ck-body-background, #fff)", strokeWidth: "1.5" }), jsx("path", { d: "M6.03258 7.43916C5.77502 7.43916 5.63096 7.29153 5.62223 7.02311L5.55675 4.96973C5.54802 4.69684 5.74446 4.5 6.02821 4.5C6.3076 4.5 6.51277 4.70131 6.50404 4.9742L6.43856 7.01864C6.42546 7.29153 6.2814 7.43916 6.03258 7.43916ZM6.03258 9.11676C5.7401 9.11676 5.5 8.9065 5.5 8.60677C5.5 8.30704 5.7401 8.09678 6.03258 8.09678C6.32506 8.09678 6.56515 8.30256 6.56515 8.60677C6.56515 8.91097 6.32069 9.11676 6.03258 9.11676Z", fill: "white" })] }) }), children: "Connect wallet" }));
124
+ return (jsx(PageContent, { onBack: null, header: locales.profileScreen_heading, children: jsx(ConnectedPageLayout, { address: address !== null && address !== void 0 ? address : '', displayName: jsx(CopyText, { value: address !== null && address !== void 0 ? address : '', children: ensName !== null && ensName !== void 0 ? ensName : truncateEthAddress(address !== null && address !== void 0 ? address : '', separator) }), avatar: address ? jsx(Avatar, { address: address }) : jsx("span", {}), beforeAvatar: jsx(ChainSelectorContainer, { initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.2 }, children: bridge ? (jsx(Suspense, { fallback: jsx(Chain, { id: chainId }), children: jsx(LazyChainSelector, {}) })) : (jsx(Chain, { id: chainId })) }, chainId !== null && chainId !== void 0 ? chainId : 'loading'), balance: balanceNode, actions: jsxs(Fragment, { children: [jsx(ActionButton, { icon: jsx(SendIcon, {}), onClick: () => {
122
125
  const firstBalanceAsset = getFirstBalanceAsset(assets);
123
126
  if (!firstBalanceAsset) {
124
127
  setRoute(routes.NO_ASSETS_AVAILABLE);
@@ -1 +1 @@
1
- {"version":3,"file":"EthereumConnected.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"EthereumConnected.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -89,7 +89,7 @@ const SolanaConnected = () => {
89
89
  : undefined;
90
90
  const avatar = address ? CustomAvatar ? jsx(CustomAvatar, { address: address }) : jsx(Avatar, { address: address }) : jsx("span", {});
91
91
  const balanceNode = balanceSol != null && !isBalanceLoading ? (jsxs(Balance, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, children: [nFormatter(Number(balanceSol)), " SOL"] }, "solana-balance")) : null;
92
- return (jsx(PageContent, { onBack: null, header: locales.profileScreen_heading, children: jsx(ConnectedPageLayout, { address: address !== null && address !== void 0 ? address : '', displayName: jsx(CopyText, { value: address !== null && address !== void 0 ? address : '', children: truncateSolanaAddress(address !== null && address !== void 0 ? address : '', separator) }), avatar: avatar, balance: balanceNode, actions: jsx(ActionButton, { icon: jsx(ReceiveIcon, {}), onClick: () => context.setRoute(routes.SOL_RECEIVE), children: "Get" }), hideBalance: context === null || context === void 0 ? void 0 : context.uiConfig.hideBalance, isBalanceLoading: isBalanceLoading, isAddressLoading: isAddressLoading, noWalletFallback: hasSolanaWallets ? (jsx(Button, { onClick: () => setRoute(routes.SOL_WALLETS), children: "Manage wallets" })) : (jsx(Button, { onClick: () => setRoute(routes.SOL_CREATE_WALLET), children: "Create Solana Wallet" })) }) }));
92
+ return (jsx(PageContent, { onBack: null, header: locales.profileScreen_heading, children: jsx(ConnectedPageLayout, { address: address !== null && address !== void 0 ? address : '', displayName: jsx(CopyText, { value: address !== null && address !== void 0 ? address : '', children: truncateSolanaAddress(address !== null && address !== void 0 ? address : '', separator) }), avatar: avatar, balance: balanceNode, actions: jsx(ActionButton, { icon: jsx(ReceiveIcon, {}), onClick: () => context.setRoute(routes.SOL_RECEIVE), children: "Get" }), hideBalance: context === null || context === void 0 ? void 0 : context.uiConfig.hideBalance, isBalanceLoading: isBalanceLoading, isAddressLoading: isAddressLoading, noWalletFallback: hasSolanaWallets ? (jsx(Button, { onClick: () => setRoute(routes.SELECT_WALLET_TO_RECOVER), children: "Manage wallets" })) : (jsx(Button, { onClick: () => setRoute(routes.SOL_CREATE_WALLET), children: "Create Solana Wallet" })) }) }));
93
93
  };
94
94
 
95
95
  export { SolanaConnected as default };
@@ -88,14 +88,20 @@ function WalletRow({ chainType, wallet, }) {
88
88
  const tag = wallet.recoveryMethod != null ? RECOVERY_METHOD_LABEL[wallet.recoveryMethod] : undefined;
89
89
  return (jsx(ProvidersButton, { children: jsxs(Button, { onClick: handleClick, children: [jsxs(ProviderLabel, { children: [display, tag && jsx(RecoveryTag, { children: tag })] }), jsx(ProviderIcon, { children: walletIcon() })] }) }));
90
90
  }
91
+ /** Connected-page routes that indicate the user navigated here from "Manage wallets" */
92
+ const CONNECTED_ROUTES = new Set([routes.CONNECTED, routes.ETH_CONNECTED, routes.SOL_CONNECTED]);
91
93
  function SelectWalletToRecover() {
92
94
  const { chainType } = useOpenfortCore();
95
+ const { previousRoute } = useOpenfort();
93
96
  const ethereumWallet = useEthereumEmbeddedWallet();
94
97
  const solanaWallet = useSolanaEmbeddedWallet();
95
98
  const embeddedWallet = chainType === ChainTypeEnum.EVM ? ethereumWallet : solanaWallet;
96
99
  const wallets = embeddedWallet.wallets;
97
100
  const list = wallets.map((wallet) => jsx(WalletRow, { chainType: chainType, wallet: wallet }, wallet.id));
98
- return (jsxs(PageContent, { onBack: routes.PROVIDERS, logoutOnBack: true, children: [jsx(ModalHeading, { children: "Select a wallet to recover" }), jsx(WalletListScroll, { children: list })] }));
101
+ // When arriving from a connected page (Manage wallets), go back there without logging out.
102
+ // When arriving from the login flow, go back to providers and log out.
103
+ const fromConnected = previousRoute != null && CONNECTED_ROUTES.has(previousRoute.route);
104
+ return (jsxs(PageContent, { onBack: fromConnected ? 'back' : routes.PROVIDERS, logoutOnBack: !fromConnected, children: [jsx(ModalHeading, { children: "Select a wallet" }), jsx(WalletListScroll, { children: list })] }));
99
105
  }
100
106
 
101
107
  export { SelectWalletToRecover as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -139,6 +139,11 @@ function useEthereumEmbeddedWallet(options) {
139
139
  ...(accountType !== DEFAULT_ACCOUNT_TYPE && { chainId: (_d = createOptions === null || createOptions === void 0 ? void 0 : createOptions.chainId) !== null && _d !== void 0 ? _d : creationChainId }),
140
140
  recoveryParams,
141
141
  });
142
+ // Set the address before fetching accounts or setting connected state.
143
+ // This prevents a race where the sync effect sees status='connected' but
144
+ // no activeEmbeddedAddress and disconnects (especially for the first wallet
145
+ // when embeddedAccounts is still empty).
146
+ setActiveEmbeddedAddress(account.address);
142
147
  await updateEmbeddedAccounts({ silent: true });
143
148
  const provider = await getEmbeddedEthereumProvider();
144
149
  const connectedWallet = buildConnectedWallet(account, 0, async () => provider, {
@@ -151,7 +156,6 @@ function useEthereumEmbeddedWallet(options) {
151
156
  provider,
152
157
  error: null,
153
158
  });
154
- setActiveEmbeddedAddress(account.address);
155
159
  (_e = createOptions === null || createOptions === void 0 ? void 0 : createOptions.onSuccess) === null || _e === void 0 ? void 0 : _e.call(createOptions, { account });
156
160
  return account;
157
161
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useEthereumEmbeddedWallet.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useEthereumEmbeddedWallet.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -219,6 +219,7 @@ const CoreOpenfortProvider = ({ children, onConnect, onDisconnect, openfortConfi
219
219
  storeActiveEmbeddedAddress,
220
220
  chainType,
221
221
  store,
222
+ walletConfig,
222
223
  });
223
224
  // Current chain for EVM provider reconfiguration
224
225
  const evmChainId = (strategy === null || strategy === void 0 ? void 0 : strategy.chainType) === ChainTypeEnum.EVM ? (bridge ? bridge.chainId : strategy === null || strategy === void 0 ? void 0 : strategy.getChainId()) : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"CoreOpenfortProvider.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"CoreOpenfortProvider.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,6 @@
1
1
  import { type ChainTypeEnum, type Openfort } from '@openfort/openfort-js';
2
2
  import type { StoreApi } from 'zustand/vanilla';
3
+ import type { OpenfortWalletConfig } from '../../components/Openfort/types';
3
4
  import type { OpenfortStore } from '../store';
4
5
  type Params = {
5
6
  openfort: Openfort;
@@ -8,13 +9,16 @@ type Params = {
8
9
  storeActiveEmbeddedAddress: OpenfortStore['activeEmbeddedAddress'];
9
10
  chainType: ChainTypeEnum;
10
11
  store: StoreApi<OpenfortStore>;
12
+ walletConfig: OpenfortWalletConfig | undefined;
11
13
  };
12
14
  /**
13
15
  * Syncs the active embedded address into the store.
14
16
  *
15
17
  * - Clears address when there are no accounts or user is logged out.
16
- * - When READY: asks the SDK for its active wallet, falls back to the first
17
- * account for the current chain.
18
+ * - When connectOnLogin is false and the session went through
19
+ * EMBEDDED_SIGNER_NOT_CONFIGURED (login flow), skips auto-seeding at READY
20
+ * so the user must pick a wallet explicitly.
21
+ * - Returning sessions (SDK starts directly at READY) always auto-seed.
18
22
  */
19
- export declare function useActiveAddressSync({ openfort, storeEmbeddedAccounts, storeEmbeddedState, storeActiveEmbeddedAddress, chainType, store, }: Params): void;
23
+ export declare function useActiveAddressSync({ openfort, storeEmbeddedAccounts, storeEmbeddedState, storeActiveEmbeddedAddress, chainType, store, walletConfig, }: Params): void;
20
24
  export {};
@@ -1,18 +1,30 @@
1
1
  import { EmbeddedState } from '@openfort/openfort-js';
2
- import { useEffect } from 'react';
2
+ import { useRef, useEffect } from 'react';
3
3
  import { firstEmbeddedAddress } from '../../core/strategyUtils.js';
4
4
 
5
5
  /**
6
6
  * Syncs the active embedded address into the store.
7
7
  *
8
8
  * - Clears address when there are no accounts or user is logged out.
9
- * - When READY: asks the SDK for its active wallet, falls back to the first
10
- * account for the current chain.
9
+ * - When connectOnLogin is false and the session went through
10
+ * EMBEDDED_SIGNER_NOT_CONFIGURED (login flow), skips auto-seeding at READY
11
+ * so the user must pick a wallet explicitly.
12
+ * - Returning sessions (SDK starts directly at READY) always auto-seed.
11
13
  */
12
- function useActiveAddressSync({ openfort, storeEmbeddedAccounts, storeEmbeddedState, storeActiveEmbeddedAddress, chainType, store, }) {
14
+ function useActiveAddressSync({ openfort, storeEmbeddedAccounts, storeEmbeddedState, storeActiveEmbeddedAddress, chainType, store, walletConfig, }) {
15
+ var _a;
16
+ const connectOnLogin = (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.connectOnLogin) !== null && _a !== void 0 ? _a : true;
17
+ // Track whether the current session went through EMBEDDED_SIGNER_NOT_CONFIGURED
18
+ // (i.e. a login flow, not a returning session). When connectOnLogin is false, we
19
+ // skip auto-seeding at READY only for login flows — returning sessions (where the
20
+ // SDK starts directly at READY with a configured signer) should always auto-seed.
21
+ const sawSignerNotConfiguredRef = useRef(false);
13
22
  useEffect(() => {
14
23
  if (!openfort || !(storeEmbeddedAccounts === null || storeEmbeddedAccounts === void 0 ? void 0 : storeEmbeddedAccounts.length)) {
15
- if (!(storeEmbeddedAccounts === null || storeEmbeddedAccounts === void 0 ? void 0 : storeEmbeddedAccounts.length)) {
24
+ // Only clear the address on genuine logout (no user). During wallet creation
25
+ // the accounts list is briefly empty while updateEmbeddedAccounts refetches —
26
+ // clearing here would undo the address that create() just set.
27
+ if (!(storeEmbeddedAccounts === null || storeEmbeddedAccounts === void 0 ? void 0 : storeEmbeddedAccounts.length) && !store.getState().user) {
16
28
  store.getState().setActiveEmbeddedAddress(undefined);
17
29
  }
18
30
  return;
@@ -23,13 +35,16 @@ function useActiveAddressSync({ openfort, storeEmbeddedAccounts, storeEmbeddedSt
23
35
  if (storeEmbeddedState === EmbeddedState.UNAUTHENTICATED || storeEmbeddedState === EmbeddedState.NONE) {
24
36
  if (!store.getState().user) {
25
37
  store.getState().setActiveEmbeddedAddress(undefined);
38
+ sawSignerNotConfiguredRef.current = false;
26
39
  }
27
40
  return;
28
41
  }
29
42
  // Bootstrap recovery: when signer is not yet configured and no address is set,
30
43
  // seed the active address so useAutoRecovery can trigger and drive state → READY.
44
+ // Skip when connectOnLogin is false — the user should explicitly choose a wallet.
31
45
  if (storeEmbeddedState === EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED) {
32
- if (storeActiveEmbeddedAddress === undefined) {
46
+ sawSignerNotConfiguredRef.current = true;
47
+ if (connectOnLogin && storeActiveEmbeddedAddress === undefined) {
33
48
  const first = firstEmbeddedAddress(storeEmbeddedAccounts, chainType);
34
49
  if (first)
35
50
  store.getState().setActiveEmbeddedAddress(first);
@@ -42,6 +57,13 @@ function useActiveAddressSync({ openfort, storeEmbeddedAccounts, storeEmbeddedSt
42
57
  // Already have an address — nothing to resolve
43
58
  if (storeActiveEmbeddedAddress !== undefined)
44
59
  return;
60
+ // Login flow with connectOnLogin=false: the session went through
61
+ // EMBEDDED_SIGNER_NOT_CONFIGURED, so don't auto-seed. The user must pick
62
+ // a wallet via the UI. create() and setActive() set the address directly,
63
+ // so they bypass this check.
64
+ if (!connectOnLogin && sawSignerNotConfiguredRef.current) {
65
+ return;
66
+ }
45
67
  // Priority 1: ask the SDK for its active wallet
46
68
  let cancelled = false;
47
69
  openfort.embeddedWallet
@@ -69,7 +91,15 @@ function useActiveAddressSync({ openfort, storeEmbeddedAccounts, storeEmbeddedSt
69
91
  return () => {
70
92
  cancelled = true;
71
93
  };
72
- }, [openfort, storeEmbeddedAccounts, storeEmbeddedState, storeActiveEmbeddedAddress, chainType, store]);
94
+ }, [
95
+ openfort,
96
+ storeEmbeddedAccounts,
97
+ storeEmbeddedState,
98
+ storeActiveEmbeddedAddress,
99
+ chainType,
100
+ store,
101
+ connectOnLogin,
102
+ ]);
73
103
  }
74
104
 
75
105
  export { useActiveAddressSync };
@@ -1 +1 @@
1
- {"version":3,"file":"useActiveAddressSync.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useActiveAddressSync.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -123,6 +123,7 @@ function useSolanaEmbeddedWallet(options) {
123
123
  accountType: AccountTypeEnum.EOA,
124
124
  recoveryParams,
125
125
  });
126
+ setActiveEmbeddedAddress(account.address);
126
127
  await updateEmbeddedAccounts({ silent: true });
127
128
  const provider = createProviderForAccount(account);
128
129
  const connectedWallet = {
@@ -139,7 +140,6 @@ function useSolanaEmbeddedWallet(options) {
139
140
  provider,
140
141
  error: null,
141
142
  });
142
- setActiveEmbeddedAddress(account.address);
143
143
  (_a = createOptions === null || createOptions === void 0 ? void 0 : createOptions.onSuccess) === null || _a === void 0 ? void 0 : _a.call(createOptions, { account });
144
144
  return account;
145
145
  }
@@ -1 +1 @@
1
- export declare const OPENFORT_VERSION = "1.0.7";
1
+ export declare const OPENFORT_VERSION = "1.0.8";
package/build/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const OPENFORT_VERSION = '1.0.7';
1
+ const OPENFORT_VERSION = '1.0.8';
2
2
 
3
3
  export { OPENFORT_VERSION };
4
4
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfort/react",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "author": "Openfort (https://www.openfort.io)",
5
5
  "license": "BSD-2-Clause license",
6
6
  "description": "The easiest way to integrate Openfort to your project.",
@@ -94,11 +94,10 @@
94
94
  "@types/styled-components": "^5.1.25",
95
95
  "@wagmi/connectors": "^6.2.0",
96
96
  "@wagmi/core": "^2.22.1",
97
- "happy-dom": "^20.8.3",
97
+ "happy-dom": "^20.8.9",
98
98
  "jsdom": "^28.1.0",
99
99
  "rollup-plugin-peer-deps-external": "^2.2.4",
100
100
  "rollup-plugin-typescript2": "^0.36.0",
101
- "styled-components": "^5.3.5",
102
101
  "typescript": "^5.0.4",
103
102
  "typescript-plugin-styled-components": "^2.0.0",
104
103
  "vitest": "^2.0.0",