@b3dotfun/sdk 0.0.77-alpha.0 → 0.0.77-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +18 -4
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +6 -3
- package/dist/cjs/global-account/react/components/B3Provider/types.d.ts +1 -0
- package/dist/cjs/global-account/react/components/B3Provider/types.js +1 -0
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +2 -2
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +162 -46
- package/dist/cjs/global-account/react/components/TurnkeyAuthModal.d.ts +8 -0
- package/dist/cjs/global-account/react/components/TurnkeyAuthModal.js +84 -0
- package/dist/cjs/global-account/react/components/index.d.ts +1 -0
- package/dist/cjs/global-account/react/components/index.js +6 -3
- package/dist/cjs/global-account/react/hooks/index.d.ts +1 -0
- package/dist/cjs/global-account/react/hooks/index.js +3 -1
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +7 -0
- package/dist/cjs/global-account/react/hooks/useTurnkeyAuth.d.ts +20 -0
- package/dist/cjs/global-account/react/hooks/useTurnkeyAuth.js +112 -0
- package/dist/cjs/global-account/react/hooks/useUserQuery.d.ts +7 -0
- package/dist/cjs/global-account/react/stores/useAuthStore.d.ts +2 -0
- package/dist/cjs/global-account/react/stores/useAuthStore.js +2 -0
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +21 -1
- package/dist/esm/global-account/react/components/B3DynamicModal.js +18 -4
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +6 -3
- package/dist/esm/global-account/react/components/B3Provider/types.d.ts +1 -0
- package/dist/esm/global-account/react/components/B3Provider/types.js +1 -0
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +2 -2
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +162 -46
- package/dist/esm/global-account/react/components/TurnkeyAuthModal.d.ts +8 -0
- package/dist/esm/global-account/react/components/TurnkeyAuthModal.js +81 -0
- package/dist/esm/global-account/react/components/index.d.ts +1 -0
- package/dist/esm/global-account/react/components/index.js +2 -0
- package/dist/esm/global-account/react/hooks/index.d.ts +1 -0
- package/dist/esm/global-account/react/hooks/index.js +1 -0
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +7 -0
- package/dist/esm/global-account/react/hooks/useTurnkeyAuth.d.ts +20 -0
- package/dist/esm/global-account/react/hooks/useTurnkeyAuth.js +106 -0
- package/dist/esm/global-account/react/hooks/useUserQuery.d.ts +7 -0
- package/dist/esm/global-account/react/stores/useAuthStore.d.ts +2 -0
- package/dist/esm/global-account/react/stores/useAuthStore.js +2 -0
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +21 -1
- package/dist/styles/index.css +1 -1
- package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
- package/dist/types/global-account/react/components/B3Provider/types.d.ts +1 -0
- package/dist/types/global-account/react/components/TurnkeyAuthModal.d.ts +8 -0
- package/dist/types/global-account/react/components/index.d.ts +1 -0
- package/dist/types/global-account/react/hooks/index.d.ts +1 -0
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +7 -0
- package/dist/types/global-account/react/hooks/useTurnkeyAuth.d.ts +20 -0
- package/dist/types/global-account/react/hooks/useUserQuery.d.ts +7 -0
- package/dist/types/global-account/react/stores/useAuthStore.d.ts +2 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +21 -1
- package/package.json +2 -2
- package/src/global-account/react/components/B3DynamicModal.tsx +26 -3
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +9 -0
- package/src/global-account/react/components/B3Provider/types.ts +2 -0
- package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +3 -3
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +170 -48
- package/src/global-account/react/components/TurnkeyAuthModal.tsx +240 -0
- package/src/global-account/react/components/index.ts +3 -0
- package/src/global-account/react/hooks/index.ts +1 -0
- package/src/global-account/react/hooks/useTurnkeyAuth.ts +138 -0
- package/src/global-account/react/stores/useAuthStore.ts +4 -0
- package/src/global-account/react/stores/useModalStore.ts +22 -0
|
@@ -7,6 +7,7 @@ exports.B3DynamicModal = B3DynamicModal;
|
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
8
|
const react_1 = require("../../../anyspend/react");
|
|
9
9
|
const AnyspendDepositHype_1 = require("../../../anyspend/react/components/AnyspendDepositHype");
|
|
10
|
+
const AnySpendDepositUpside_1 = require("../../../anyspend/react/components/AnySpendDepositUpside");
|
|
10
11
|
const AnySpendStakeUpside_1 = require("../../../anyspend/react/components/AnySpendStakeUpside");
|
|
11
12
|
const AnySpendStakeUpsideExactIn_1 = require("../../../anyspend/react/components/AnySpendStakeUpsideExactIn");
|
|
12
13
|
const react_2 = require("../../../global-account/react");
|
|
@@ -25,10 +26,10 @@ const NotificationsContent_1 = __importDefault(require("./ManageAccount/Notifica
|
|
|
25
26
|
const RequestPermissions_1 = require("./RequestPermissions/RequestPermissions");
|
|
26
27
|
const Send_1 = require("./Send/Send");
|
|
27
28
|
const SignInWithB3Flow_1 = require("./SignInWithB3/SignInWithB3Flow");
|
|
29
|
+
const TurnkeyAuthModal_1 = require("./TurnkeyAuthModal");
|
|
28
30
|
const index_1 = require("./Toast/index");
|
|
29
31
|
const dialog_1 = require("./ui/dialog");
|
|
30
32
|
const drawer_1 = require("./ui/drawer");
|
|
31
|
-
const AnySpendDepositUpside_1 = require("../../../anyspend/react/components/AnySpendDepositUpside");
|
|
32
33
|
const debug = (0, debug_1.debugB3React)("B3DynamicModal");
|
|
33
34
|
function B3DynamicModal() {
|
|
34
35
|
const isOpen = (0, react_2.useModalStore)(state => state.isOpen);
|
|
@@ -63,6 +64,7 @@ function B3DynamicModal() {
|
|
|
63
64
|
"anySpendBuySpin",
|
|
64
65
|
"anySpendOrderHistory",
|
|
65
66
|
"signInWithB3",
|
|
67
|
+
"turnkeyAuth",
|
|
66
68
|
"anySpendSignatureMint",
|
|
67
69
|
"anySpendBondKit",
|
|
68
70
|
"linkAccount",
|
|
@@ -86,10 +88,12 @@ function B3DynamicModal() {
|
|
|
86
88
|
];
|
|
87
89
|
// Check if current content type is in freestyle types
|
|
88
90
|
const isFreestyleType = freestyleTypes.includes(contentType?.type);
|
|
91
|
+
// Determine if modal should be closable - defaults to true unless explicitly set to false
|
|
92
|
+
const isClosable = contentType?.closable !== false;
|
|
89
93
|
const hideCloseButton = true;
|
|
90
94
|
// Build content class using cn utility
|
|
91
95
|
// eslint-disable-next-line tailwindcss/no-custom-classname
|
|
92
|
-
const contentClass = (0, cn_1.cn)("b3-modal", theme === "dark" && "dark", fullWidthTypes.includes(contentType?.type) && "w-full", isFreestyleType && "b3-modal-freestyle", contentType?.type === "signInWithB3" && "p-0", contentType?.type === "anySpend" && "md:p-0", contentType?.type === "send" && "p-0", contentType?.type === "manageAccount" && " md:p-0 md:pt-2", contentType?.type === "linkAccount" && "md:p-0");
|
|
96
|
+
const contentClass = (0, cn_1.cn)("b3-modal", theme === "dark" && "dark", fullWidthTypes.includes(contentType?.type) && "w-full", isFreestyleType && "b3-modal-freestyle", contentType?.type === "signInWithB3" && "p-0", contentType?.type === "turnkeyAuth" && "p-0", contentType?.type === "anySpend" && "md:p-0", contentType?.type === "send" && "p-0", contentType?.type === "manageAccount" && " md:p-0 md:pt-2", contentType?.type === "linkAccount" && "md:p-0");
|
|
93
97
|
debug("contentType", contentType);
|
|
94
98
|
const renderContent = () => {
|
|
95
99
|
if (!contentType)
|
|
@@ -97,6 +101,8 @@ function B3DynamicModal() {
|
|
|
97
101
|
switch (contentType.type) {
|
|
98
102
|
case "signInWithB3":
|
|
99
103
|
return (0, jsx_runtime_1.jsx)(SignInWithB3Flow_1.SignInWithB3Flow, { ...contentType });
|
|
104
|
+
case "turnkeyAuth":
|
|
105
|
+
return (0, jsx_runtime_1.jsx)(TurnkeyAuthModal_1.TurnkeyAuthModal, { ...contentType });
|
|
100
106
|
case "requestPermissions":
|
|
101
107
|
return (0, jsx_runtime_1.jsx)(RequestPermissions_1.RequestPermissions, { ...contentType });
|
|
102
108
|
case "manageAccount":
|
|
@@ -154,12 +160,20 @@ function B3DynamicModal() {
|
|
|
154
160
|
const ModalContent = isMobile ? drawer_1.DrawerContent : dialog_1.DialogContent;
|
|
155
161
|
const ModalTitle = isMobile ? drawer_1.DrawerTitle : dialog_1.DialogTitle;
|
|
156
162
|
const ModalDescription = isMobile ? drawer_1.DrawerDescription : dialog_1.DialogDescription;
|
|
157
|
-
|
|
163
|
+
// Create a wrapper for onOpenChange that respects closable property
|
|
164
|
+
const handleOpenChange = (open) => {
|
|
165
|
+
// Only allow closing if the modal is closable
|
|
166
|
+
if (!open && !isClosable) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
setB3ModalOpen(open);
|
|
170
|
+
};
|
|
171
|
+
return ((0, jsx_runtime_1.jsxs)(ModalComponent, { open: isOpen, onOpenChange: handleOpenChange, children: [(0, jsx_runtime_1.jsxs)(ModalContent, { className: (0, cn_1.cn)(contentClass, "rounded-2xl bg-white shadow-xl dark:bg-gray-900", "border border-gray-200 dark:border-gray-800", (contentType?.type === "manageAccount" ||
|
|
158
172
|
contentType?.type === "deposit" ||
|
|
159
173
|
contentType?.type === "send" ||
|
|
160
174
|
contentType?.type === "avatarEditor" ||
|
|
161
175
|
contentType?.type === "notifications") &&
|
|
162
|
-
"p-0", "mx-auto w-full max-w-md sm:max-w-lg"), hideCloseButton: hideCloseButton, children: [(0, jsx_runtime_1.jsx)(ModalTitle, { className: "sr-only hidden", children: contentType?.type || "Modal" }), (0, jsx_runtime_1.jsx)(ModalDescription, { className: "sr-only hidden", children: contentType?.type || "Modal Body" }), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("no-scrollbar flex max-h-[90dvh] flex-col overflow-auto sm:max-h-[80dvh]"), children: [!hideCloseButton && ((0, jsx_runtime_1.jsxs)("button", { onClick: navigateBack, className: "flex items-center gap-2 px-6 py-4 text-gray-600 transition-colors hover:text-gray-900 dark:text-gray-400 dark:hover:text-white", children: [(0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("path", { d: "M15.8337 10H4.16699", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }), (0, jsx_runtime_1.jsx)("path", { d: "M10.0003 15.8334L4.16699 10L10.0003 4.16669", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }), (0, jsx_runtime_1.jsx)("span", { className: "font-inter text-sm font-semibold", children: "Back" })] })), (0, jsx_runtime_1.jsx)("div", { className: "flex-1", children: renderContent() }), (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { children: toasts.length > 0 && ((0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { initial: { height: 0 }, animate: { height: "auto" }, exit: { height: 0 }, transition: { duration: 0.3, ease: "easeInOut" }, className: "toast-section relative z-10 overflow-hidden bg-white dark:border-gray-800 dark:bg-gray-900", children: (0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -10 }, transition: { duration: 0.2, delay: 0.1 }, className: "p-4 pt-0", children: (0, jsx_runtime_1.jsx)(index_1.ToastContainer, { toasts: toasts, onDismiss: removeToast, theme: theme }) }) })) })] })] }), isOpen && ((0, jsx_runtime_1.jsx)("style", { children: `
|
|
176
|
+
"p-0", "mx-auto w-full max-w-md sm:max-w-lg"), hideCloseButton: hideCloseButton, onEscapeKeyDown: !isClosable ? e => e.preventDefault() : undefined, onPointerDownOutside: !isClosable ? e => e.preventDefault() : undefined, onInteractOutside: !isClosable ? e => e.preventDefault() : undefined, children: [(0, jsx_runtime_1.jsx)(ModalTitle, { className: "sr-only hidden", children: contentType?.type || "Modal" }), (0, jsx_runtime_1.jsx)(ModalDescription, { className: "sr-only hidden", children: contentType?.type || "Modal Body" }), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("b3-modal-content no-scrollbar dark:bg-b3-background flex max-h-[90dvh] flex-col overflow-auto sm:max-h-[80dvh]"), children: [!hideCloseButton && ((0, jsx_runtime_1.jsxs)("button", { onClick: navigateBack, className: "flex items-center gap-2 px-6 py-4 text-gray-600 transition-colors hover:text-gray-900 dark:text-gray-400 dark:hover:text-white", children: [(0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [(0, jsx_runtime_1.jsx)("path", { d: "M15.8337 10H4.16699", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }), (0, jsx_runtime_1.jsx)("path", { d: "M10.0003 15.8334L4.16699 10L10.0003 4.16669", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }), (0, jsx_runtime_1.jsx)("span", { className: "font-inter text-sm font-semibold", children: "Back" })] })), (0, jsx_runtime_1.jsx)("div", { className: "flex-1", children: renderContent() }), (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { children: toasts.length > 0 && ((0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { initial: { height: 0 }, animate: { height: "auto" }, exit: { height: 0 }, transition: { duration: 0.3, ease: "easeInOut" }, className: "toast-section relative z-10 overflow-hidden bg-white dark:border-gray-800 dark:bg-gray-900", children: (0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -10 }, transition: { duration: 0.2, delay: 0.1 }, className: "p-4 pt-0", children: (0, jsx_runtime_1.jsx)(index_1.ToastContainer, { toasts: toasts, onDismiss: removeToast, theme: theme }) }) })) })] })] }), isOpen && ((0, jsx_runtime_1.jsx)("style", { children: `
|
|
163
177
|
.modal-inner-content {
|
|
164
178
|
transition: margin-bottom 0.3s ease-in-out;
|
|
165
179
|
margin-bottom: ${toasts.length > 0 ? "0px" : "23px"} !important;
|
|
@@ -9,7 +9,7 @@ import { B3ContextType } from "./types";
|
|
|
9
9
|
/**
|
|
10
10
|
* Main B3Provider component
|
|
11
11
|
*/
|
|
12
|
-
export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey, toaster: _toaster, clientType, rpcUrls, partnerId, onConnect, connectors, overrideDefaultConnectors, createClientReferenceId, }: {
|
|
12
|
+
export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey, toaster: _toaster, clientType, rpcUrls, partnerId, onConnect, connectors, overrideDefaultConnectors, createClientReferenceId, enableTurnkey, }: {
|
|
13
13
|
theme: "light" | "dark";
|
|
14
14
|
children: React.ReactNode;
|
|
15
15
|
accountOverride?: Account;
|
|
@@ -27,11 +27,12 @@ export declare function B3Provider({ theme, children, accountOverride, environme
|
|
|
27
27
|
connectors?: CreateConnectorFn[];
|
|
28
28
|
overrideDefaultConnectors?: boolean;
|
|
29
29
|
createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
|
|
30
|
+
enableTurnkey?: boolean;
|
|
30
31
|
}): import("react/jsx-runtime").JSX.Element;
|
|
31
32
|
/**
|
|
32
33
|
* Inner provider component that provides the actual B3Context
|
|
33
34
|
*/
|
|
34
|
-
export declare function InnerProvider({ children, accountOverride, environment, defaultPermissions, automaticallySetFirstEoa, theme, clientType, partnerId, createClientReferenceId, }: {
|
|
35
|
+
export declare function InnerProvider({ children, accountOverride, environment, defaultPermissions, automaticallySetFirstEoa, theme, clientType, partnerId, createClientReferenceId, enableTurnkey, }: {
|
|
35
36
|
children: React.ReactNode;
|
|
36
37
|
accountOverride?: Account;
|
|
37
38
|
environment: B3ContextType["environment"];
|
|
@@ -41,4 +42,5 @@ export declare function InnerProvider({ children, accountOverride, environment,
|
|
|
41
42
|
clientType?: ClientType;
|
|
42
43
|
partnerId: string;
|
|
43
44
|
createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
|
|
45
|
+
enableTurnkey?: boolean;
|
|
44
46
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -34,7 +34,7 @@ const queryClient = new react_query_1.QueryClient();
|
|
|
34
34
|
*/
|
|
35
35
|
function B3Provider({ theme = "light", children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey,
|
|
36
36
|
// deprecated since v0.0.87
|
|
37
|
-
toaster: _toaster, clientType = "rest", rpcUrls, partnerId, onConnect, connectors, overrideDefaultConnectors = false, createClientReferenceId, }) {
|
|
37
|
+
toaster: _toaster, clientType = "rest", rpcUrls, partnerId, onConnect, connectors, overrideDefaultConnectors = false, createClientReferenceId, enableTurnkey = false, }) {
|
|
38
38
|
// Initialize Google Analytics on mount
|
|
39
39
|
(0, react_2.useEffect)(() => {
|
|
40
40
|
(0, analytics_1.loadGA4Script)();
|
|
@@ -44,22 +44,24 @@ toaster: _toaster, clientType = "rest", rpcUrls, partnerId, onConnect, connector
|
|
|
44
44
|
(0, client_manager_1.setClientType)(clientType);
|
|
45
45
|
}, [clientType]);
|
|
46
46
|
const wagmiConfig = (0, createWagmiConfig_1.createWagmiConfig)({ partnerId, rpcUrls, connectors, overrideDefaultConnectors });
|
|
47
|
-
return ((0, jsx_runtime_1.jsx)(react_3.ThirdwebProvider, { children: (0, jsx_runtime_1.jsx)(wagmi_1.WagmiProvider, { config: wagmiConfig, reconnectOnMount: false, children: (0, jsx_runtime_1.jsx)(react_query_1.QueryClientProvider, { client: queryClient, children: (0, jsx_runtime_1.jsx)(react_1.TooltipProvider, { children: (0, jsx_runtime_1.jsx)(index_1.ToastProvider, { children: (0, jsx_runtime_1.jsx)(LocalSDKProvider_1.LocalSDKProvider, { onConnectCallback: onConnect, children: (0, jsx_runtime_1.jsxs)(InnerProvider, { accountOverride: accountOverride, environment: environment, theme: theme, automaticallySetFirstEoa: !!automaticallySetFirstEoa, clientType: clientType, partnerId: partnerId, createClientReferenceId: createClientReferenceId, children: [(0, jsx_runtime_1.jsx)(ToastContextConnector, {}), (0, jsx_runtime_1.jsxs)(react_1.RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, (0, jsx_runtime_1.jsx)(StyleRoot_1.StyleRoot, { id: "b3-root" })] })] }) }) }) }) }) }) }));
|
|
47
|
+
return ((0, jsx_runtime_1.jsx)(react_3.ThirdwebProvider, { children: (0, jsx_runtime_1.jsx)(wagmi_1.WagmiProvider, { config: wagmiConfig, reconnectOnMount: false, children: (0, jsx_runtime_1.jsx)(react_query_1.QueryClientProvider, { client: queryClient, children: (0, jsx_runtime_1.jsx)(react_1.TooltipProvider, { children: (0, jsx_runtime_1.jsx)(index_1.ToastProvider, { children: (0, jsx_runtime_1.jsx)(LocalSDKProvider_1.LocalSDKProvider, { onConnectCallback: onConnect, children: (0, jsx_runtime_1.jsxs)(InnerProvider, { accountOverride: accountOverride, environment: environment, theme: theme, automaticallySetFirstEoa: !!automaticallySetFirstEoa, clientType: clientType, partnerId: partnerId, createClientReferenceId: createClientReferenceId, enableTurnkey: enableTurnkey, children: [(0, jsx_runtime_1.jsx)(ToastContextConnector, {}), (0, jsx_runtime_1.jsxs)(react_1.RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, (0, jsx_runtime_1.jsx)(StyleRoot_1.StyleRoot, { id: "b3-root" })] })] }) }) }) }) }) }) }));
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Inner provider component that provides the actual B3Context
|
|
51
51
|
*/
|
|
52
|
-
function InnerProvider({ children, accountOverride, environment, defaultPermissions = DEFAULT_PERMISSIONS, automaticallySetFirstEoa, theme = "light", clientType = "socket", partnerId, createClientReferenceId, }) {
|
|
52
|
+
function InnerProvider({ children, accountOverride, environment, defaultPermissions = DEFAULT_PERMISSIONS, automaticallySetFirstEoa, theme = "light", clientType = "socket", partnerId, createClientReferenceId, enableTurnkey, }) {
|
|
53
53
|
const activeAccount = (0, react_3.useActiveAccount)();
|
|
54
54
|
const [manuallySelectedWallet, setManuallySelectedWallet] = (0, react_2.useState)(undefined);
|
|
55
55
|
const wallets = (0, react_3.useConnectedWallets)();
|
|
56
56
|
const isAuthenticated = (0, react_1.useAuthStore)(state => state.isAuthenticated);
|
|
57
57
|
const isConnected = (0, react_1.useAuthStore)(state => state.isConnected);
|
|
58
|
+
const justCompletedLogin = (0, react_1.useAuthStore)(state => state.justCompletedLogin);
|
|
58
59
|
const setActiveWallet = (0, react_3.useSetActiveWallet)();
|
|
59
60
|
const { user, setUser, refetchUser } = (0, react_1.useAuthentication)(partnerId);
|
|
60
61
|
debug("@@B3Provider:isConnected", isConnected);
|
|
61
62
|
debug("@@wallets", wallets);
|
|
62
63
|
debug("@@B3Provider:user", user);
|
|
64
|
+
debug("@@B3Provider:justCompletedLogin", justCompletedLogin);
|
|
63
65
|
// Use given accountOverride or activeAccount from thirdweb
|
|
64
66
|
const effectiveAccount = isAuthenticated ? accountOverride || activeAccount : undefined;
|
|
65
67
|
const setWallet = (0, react_2.useCallback)((wallet) => {
|
|
@@ -104,6 +106,7 @@ function InnerProvider({ children, accountOverride, environment, defaultPermissi
|
|
|
104
106
|
clientType,
|
|
105
107
|
partnerId: partnerId,
|
|
106
108
|
createClientReferenceId,
|
|
109
|
+
enableTurnkey,
|
|
107
110
|
}, children: (0, jsx_runtime_1.jsx)(InnerProvider2, { children: children }) }));
|
|
108
111
|
}
|
|
109
112
|
const InnerProvider2 = ({ children }) => {
|
|
@@ -13,11 +13,11 @@ const SettingsIcon = () => {
|
|
|
13
13
|
};
|
|
14
14
|
const BottomNavigation = () => {
|
|
15
15
|
const setB3ModalContentType = (0, react_1.useModalStore)(state => state.setB3ModalContentType);
|
|
16
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: "b3-modal-bottom-navigation sticky bottom-0 left-0 w-full rounded-b-xl border-t border-gray-200 bg-[#FAFAFA]", children: (0, jsx_runtime_1.jsxs)(react_1.TabsListPrimitive, { className: "flex h-[68px] w-full items-center justify-center gap-4 border-none bg-transparent", children: [(0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "home", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B]", children: [(0, jsx_runtime_1.jsx)(HomeIcon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Home" })] }), (0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "swap", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B]", onClick: () => {
|
|
16
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "b3-modal-bottom-navigation sticky bottom-0 left-0 w-full rounded-b-xl border-t border-gray-200 bg-[#FAFAFA]", children: (0, jsx_runtime_1.jsxs)(react_1.TabsListPrimitive, { className: "flex h-[68px] w-full items-center justify-center gap-4 border-none bg-transparent", children: [(0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "home", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", children: [(0, jsx_runtime_1.jsx)(HomeIcon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Home" })] }), (0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "swap", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", onClick: () => {
|
|
17
17
|
setB3ModalContentType({
|
|
18
18
|
type: "anySpend",
|
|
19
19
|
showBackButton: true,
|
|
20
20
|
});
|
|
21
|
-
}, children: [(0, jsx_runtime_1.jsx)(SwapIcon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Swap" })] }), (0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B]", children: [(0, jsx_runtime_1.jsx)(SettingsIcon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Settings" })] })] }) }));
|
|
21
|
+
}, children: [(0, jsx_runtime_1.jsx)(SwapIcon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Swap" })] }), (0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", children: [(0, jsx_runtime_1.jsx)(SettingsIcon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Settings" })] })] }) }));
|
|
22
22
|
};
|
|
23
23
|
exports.default = BottomNavigation;
|
|
@@ -16,16 +16,18 @@ const MAX_REFETCH_ATTEMPTS = 20;
|
|
|
16
16
|
* Handles different login providers, authentication steps, and session key management
|
|
17
17
|
*/
|
|
18
18
|
function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin = false, source = "signInWithB3Button", signersEnabled = false, }) {
|
|
19
|
-
const { automaticallySetFirstEoa } = (0, react_1.useB3)();
|
|
19
|
+
const { automaticallySetFirstEoa, user, refetchUser, enableTurnkey } = (0, react_1.useB3)();
|
|
20
20
|
const [step, setStep] = (0, react_2.useState)(source === "requestPermissions" ? null : "login");
|
|
21
21
|
const [sessionKeyAdded, setSessionKeyAdded] = (0, react_2.useState)(source === "requestPermissions" ? true : false);
|
|
22
|
-
const { setB3ModalContentType, setB3ModalOpen, isOpen } = (0, react_1.useModalStore)();
|
|
22
|
+
const { setB3ModalContentType, setB3ModalOpen, isOpen, contentType } = (0, react_1.useModalStore)();
|
|
23
23
|
const account = (0, react_3.useActiveAccount)();
|
|
24
24
|
const isAuthenticating = (0, react_1.useAuthStore)(state => state.isAuthenticating);
|
|
25
25
|
const isAuthenticated = (0, react_1.useAuthStore)(state => state.isAuthenticated);
|
|
26
26
|
const isConnected = (0, react_1.useAuthStore)(state => state.isConnected);
|
|
27
|
+
const setJustCompletedLogin = (0, react_1.useAuthStore)(state => state.setJustCompletedLogin);
|
|
27
28
|
const [refetchCount, setRefetchCount] = (0, react_2.useState)(0);
|
|
28
29
|
const [refetchError, setRefetchError] = (0, react_2.useState)(null);
|
|
30
|
+
const [turnkeyAuthCompleted, setTurnkeyAuthCompleted] = (0, react_2.useState)(false);
|
|
29
31
|
const { data: signers, refetch: refetchSigners, isFetching: isFetchingSigners, } = (0, react_1.useGetAllTWSigners)({
|
|
30
32
|
chain,
|
|
31
33
|
accountAddress: account?.address,
|
|
@@ -55,6 +57,104 @@ function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onE
|
|
|
55
57
|
setRefetchQueued(false);
|
|
56
58
|
}, backoffDelay);
|
|
57
59
|
}, [refetchCount, refetchSigners, onError, setRefetchQueued, refetchQueued]);
|
|
60
|
+
// Extract the completion flow logic to be reused
|
|
61
|
+
const handlePostTurnkeyFlow = (0, react_2.useCallback)(() => {
|
|
62
|
+
debug("Running post-Turnkey flow logic");
|
|
63
|
+
// Check if we already have a signer for this partner
|
|
64
|
+
const hasExistingSigner = signers?.some(signer => signer.partner.id === partnerId);
|
|
65
|
+
if (hasExistingSigner) {
|
|
66
|
+
// Path 1: User already has a signer for this partner
|
|
67
|
+
setSessionKeyAdded(true);
|
|
68
|
+
onSessionKeySuccess?.();
|
|
69
|
+
if (closeAfterLogin) {
|
|
70
|
+
setB3ModalOpen(false);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
setB3ModalContentType({
|
|
74
|
+
type: "manageAccount",
|
|
75
|
+
chain,
|
|
76
|
+
partnerId,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if (signersEnabled) {
|
|
81
|
+
// Path 2: No existing signer, but signers are enabled
|
|
82
|
+
if (source !== "requestPermissions") {
|
|
83
|
+
// Navigate to permissions step to request new signer
|
|
84
|
+
setStep("permissions");
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// Already in request permissions flow, retry fetching signers
|
|
88
|
+
handleRefetchSigners();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Path 3: No existing signer and signers are not enabled
|
|
93
|
+
// Default handling for when no signer exists and signers are not enabled
|
|
94
|
+
if (closeAfterLogin) {
|
|
95
|
+
setB3ModalOpen(false);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// if not closed, default to manage account
|
|
99
|
+
setB3ModalContentType({
|
|
100
|
+
type: "manageAccount",
|
|
101
|
+
chain,
|
|
102
|
+
partnerId,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}, [
|
|
107
|
+
signers,
|
|
108
|
+
partnerId,
|
|
109
|
+
onSessionKeySuccess,
|
|
110
|
+
closeAfterLogin,
|
|
111
|
+
setB3ModalOpen,
|
|
112
|
+
setB3ModalContentType,
|
|
113
|
+
chain,
|
|
114
|
+
source,
|
|
115
|
+
signersEnabled,
|
|
116
|
+
handleRefetchSigners,
|
|
117
|
+
setSessionKeyAdded,
|
|
118
|
+
]);
|
|
119
|
+
// Define handleTurnkeySuccess before the useEffect that uses it
|
|
120
|
+
const handleTurnkeySuccess = (0, react_2.useCallback)(async (user) => {
|
|
121
|
+
debug("Turnkey authentication successful - setting completed flag", { user });
|
|
122
|
+
// Set completed flag FIRST before any async operations
|
|
123
|
+
setTurnkeyAuthCompleted(true);
|
|
124
|
+
// Refetch user to update the user state with Turnkey ID
|
|
125
|
+
debug("Refetching user after Turnkey success...");
|
|
126
|
+
await refetchUser();
|
|
127
|
+
debug("User refetched successfully");
|
|
128
|
+
// After user data is refreshed, close Turnkey modal and go back to sign-in flow
|
|
129
|
+
debug("Switching back to signInWithB3 modal");
|
|
130
|
+
setB3ModalContentType({
|
|
131
|
+
type: "signInWithB3",
|
|
132
|
+
strategies,
|
|
133
|
+
onLoginSuccess,
|
|
134
|
+
onSessionKeySuccess,
|
|
135
|
+
onError,
|
|
136
|
+
chain,
|
|
137
|
+
sessionKeyAddress,
|
|
138
|
+
partnerId,
|
|
139
|
+
closeAfterLogin,
|
|
140
|
+
source,
|
|
141
|
+
signersEnabled,
|
|
142
|
+
});
|
|
143
|
+
// The useEffect will re-run with updated user data to complete the sign-in process
|
|
144
|
+
}, [
|
|
145
|
+
refetchUser,
|
|
146
|
+
setB3ModalContentType,
|
|
147
|
+
strategies,
|
|
148
|
+
onLoginSuccess,
|
|
149
|
+
onSessionKeySuccess,
|
|
150
|
+
onError,
|
|
151
|
+
chain,
|
|
152
|
+
sessionKeyAddress,
|
|
153
|
+
partnerId,
|
|
154
|
+
closeAfterLogin,
|
|
155
|
+
source,
|
|
156
|
+
signersEnabled,
|
|
157
|
+
]);
|
|
58
158
|
// Handle post-login flow after signers are loaded
|
|
59
159
|
(0, react_2.useEffect)(() => {
|
|
60
160
|
debug("@@SignInWithB3Flow:useEffect", {
|
|
@@ -65,41 +165,46 @@ function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onE
|
|
|
65
165
|
isOpen,
|
|
66
166
|
source,
|
|
67
167
|
});
|
|
68
|
-
if (isConnected && isAuthenticated) {
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
if (hasExistingSigner) {
|
|
72
|
-
setSessionKeyAdded(true);
|
|
73
|
-
onSessionKeySuccess?.();
|
|
74
|
-
if (closeAfterLogin) {
|
|
75
|
-
setB3ModalOpen(false);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
setB3ModalContentType({
|
|
79
|
-
type: "manageAccount",
|
|
80
|
-
chain,
|
|
81
|
-
partnerId,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
else if (source !== "requestPermissions") {
|
|
86
|
-
if (signersEnabled)
|
|
87
|
-
setStep("permissions");
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
if (signersEnabled)
|
|
91
|
-
handleRefetchSigners();
|
|
92
|
-
}
|
|
93
|
-
// Default handling
|
|
168
|
+
if (isConnected && isAuthenticated && user) {
|
|
169
|
+
// Mark that login just completed BEFORE opening manage account or closing modal
|
|
170
|
+
// This allows Turnkey modal to show (if enableTurnkey is true)
|
|
94
171
|
if (closeAfterLogin) {
|
|
95
|
-
|
|
172
|
+
setJustCompletedLogin(true);
|
|
96
173
|
}
|
|
97
|
-
// if
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
174
|
+
// Check if we should show Turnkey login form
|
|
175
|
+
// Show if enableTurnkey is true AND user just logged in AND hasn't completed Turnkey auth in this session
|
|
176
|
+
// For new users (!turnkeyId): Show email form
|
|
177
|
+
// For returning users (turnkeyId && turnkeyEmail): Auto-skip to OTP
|
|
178
|
+
// Also check that we're not already showing the Turnkey modal
|
|
179
|
+
const hasTurnkeyId = user?.partnerIds?.turnkeyId;
|
|
180
|
+
const hasTurnkeyEmail = !!user?.email;
|
|
181
|
+
const isTurnkeyModalCurrentlyOpen = contentType?.type === "turnkeyAuth";
|
|
182
|
+
const shouldShowTurnkeyModal = enableTurnkey &&
|
|
183
|
+
user &&
|
|
184
|
+
!turnkeyAuthCompleted &&
|
|
185
|
+
!isTurnkeyModalCurrentlyOpen &&
|
|
186
|
+
(!hasTurnkeyId || (hasTurnkeyId && hasTurnkeyEmail));
|
|
187
|
+
if (shouldShowTurnkeyModal) {
|
|
188
|
+
// Extract email from user object - check partnerIds.turnkeyEmail first, then twProfiles, then user.email
|
|
189
|
+
const email = user?.email || user?.twProfiles?.find((profile) => profile.details?.email)?.details?.email;
|
|
190
|
+
// Open Turnkey modal through the modal store
|
|
191
|
+
setB3ModalContentType({
|
|
192
|
+
type: "turnkeyAuth",
|
|
193
|
+
onSuccess: handleTurnkeySuccess,
|
|
194
|
+
onClose: () => {
|
|
195
|
+
// After closing Turnkey modal, continue with the rest of the flow
|
|
196
|
+
setTurnkeyAuthCompleted(true);
|
|
197
|
+
debug("Turnkey modal closed, running post-Turnkey flow");
|
|
198
|
+
handlePostTurnkeyFlow();
|
|
199
|
+
},
|
|
200
|
+
initialEmail: email,
|
|
201
|
+
skipToOtp: !!(hasTurnkeyId && hasTurnkeyEmail),
|
|
202
|
+
closable: false, // Turnkey modal cannot be closed until auth is complete
|
|
203
|
+
});
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
// Normal flow continues after Turnkey auth is complete (or if not needed)
|
|
207
|
+
handlePostTurnkeyFlow();
|
|
103
208
|
}
|
|
104
209
|
}, [
|
|
105
210
|
signers,
|
|
@@ -117,6 +222,13 @@ function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onE
|
|
|
117
222
|
isAuthenticating,
|
|
118
223
|
isAuthenticated,
|
|
119
224
|
isOpen,
|
|
225
|
+
setJustCompletedLogin,
|
|
226
|
+
user,
|
|
227
|
+
enableTurnkey,
|
|
228
|
+
turnkeyAuthCompleted,
|
|
229
|
+
handleTurnkeySuccess,
|
|
230
|
+
contentType,
|
|
231
|
+
handlePostTurnkeyFlow,
|
|
120
232
|
]);
|
|
121
233
|
debug("render", {
|
|
122
234
|
step,
|
|
@@ -171,24 +283,28 @@ function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onE
|
|
|
171
283
|
});
|
|
172
284
|
}
|
|
173
285
|
}, [chain, onError, onSessionKeySuccessEnhanced, sessionKeyAddress, setB3ModalContentType, step]);
|
|
286
|
+
// Render content based on current step/state
|
|
287
|
+
let content = null;
|
|
174
288
|
// Display error if refetch limit exceeded
|
|
175
289
|
if (refetchError) {
|
|
176
|
-
|
|
290
|
+
content = ((0, jsx_runtime_1.jsx)(LoginStep_1.LoginStepContainer, { partnerId: partnerId, children: (0, jsx_runtime_1.jsx)("div", { className: "p-4 text-center text-red-500", children: refetchError }) }));
|
|
177
291
|
}
|
|
178
|
-
if (isAuthenticating || (isFetchingSigners && step === "login") || source === "requestPermissions") {
|
|
179
|
-
|
|
292
|
+
else if (isAuthenticating || (isFetchingSigners && step === "login") || source === "requestPermissions") {
|
|
293
|
+
content = ((0, jsx_runtime_1.jsx)(LoginStep_1.LoginStepContainer, { partnerId: partnerId, children: (0, jsx_runtime_1.jsx)("div", { className: "my-8 flex min-h-[350px] items-center justify-center", children: (0, jsx_runtime_1.jsx)(react_1.Loading, { variant: "white", size: "lg" }) }) }));
|
|
180
294
|
}
|
|
181
|
-
if (step === "login") {
|
|
295
|
+
else if (step === "login") {
|
|
182
296
|
// Custom strategy
|
|
183
297
|
if (strategies?.[0] === "privy") {
|
|
184
|
-
|
|
298
|
+
content = (0, jsx_runtime_1.jsx)(SignInWithB3Privy_1.SignInWithB3Privy, { onSuccess: handleLoginSuccess, chain: chain });
|
|
299
|
+
}
|
|
300
|
+
else if (strategies) {
|
|
301
|
+
// Strategies are explicitly provided
|
|
302
|
+
content = ((0, jsx_runtime_1.jsx)(LoginStepCustom_1.LoginStepCustom, { strategies: strategies, chain: chain, onSuccess: handleLoginSuccess, onError: onError, automaticallySetFirstEoa: !!automaticallySetFirstEoa }));
|
|
185
303
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
304
|
+
else {
|
|
305
|
+
// Default to handle all strategies we support
|
|
306
|
+
content = (0, jsx_runtime_1.jsx)(LoginStep_1.LoginStep, { chain: chain, onSuccess: handleLoginSuccess, onError: onError });
|
|
189
307
|
}
|
|
190
|
-
// Default to handle all strategies we support
|
|
191
|
-
return (0, jsx_runtime_1.jsx)(LoginStep_1.LoginStep, { chain: chain, onSuccess: handleLoginSuccess, onError: onError });
|
|
192
308
|
}
|
|
193
|
-
return
|
|
309
|
+
return content;
|
|
194
310
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface TurnkeyAuthModalProps {
|
|
2
|
+
onClose: () => void;
|
|
3
|
+
onSuccess: (_user: any) => void;
|
|
4
|
+
initialEmail?: string;
|
|
5
|
+
skipToOtp?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function TurnkeyAuthModal({ onClose, onSuccess, initialEmail, skipToOtp }: TurnkeyAuthModalProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TurnkeyAuthModal = TurnkeyAuthModal;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const useTurnkeyAuth_1 = require("../hooks/useTurnkeyAuth");
|
|
7
|
+
function TurnkeyAuthModal({ onClose, onSuccess, initialEmail = "", skipToOtp = false }) {
|
|
8
|
+
const [step, setStep] = (0, react_1.useState)(skipToOtp ? "otp" : "email");
|
|
9
|
+
const [email, setEmail] = (0, react_1.useState)(initialEmail);
|
|
10
|
+
const [otpCode, setOtpCode] = (0, react_1.useState)("");
|
|
11
|
+
const [otpId, setOtpId] = (0, react_1.useState)("");
|
|
12
|
+
const autoSubmitTriggeredRef = (0, react_1.useRef)(false);
|
|
13
|
+
const { initiateLogin, verifyOtp, isLoading, error, clearError } = (0, useTurnkeyAuth_1.useTurnkeyAuth)();
|
|
14
|
+
// Update email when initialEmail changes
|
|
15
|
+
(0, react_1.useEffect)(() => {
|
|
16
|
+
if (initialEmail && initialEmail !== email) {
|
|
17
|
+
setEmail(initialEmail);
|
|
18
|
+
}
|
|
19
|
+
}, [initialEmail, email]);
|
|
20
|
+
// Auto-submit email form if skipToOtp is true - triggers on mount when skipToOtp=true
|
|
21
|
+
(0, react_1.useEffect)(() => {
|
|
22
|
+
if (skipToOtp && email && step === "otp" && !otpId && !isLoading && !autoSubmitTriggeredRef.current) {
|
|
23
|
+
autoSubmitTriggeredRef.current = true;
|
|
24
|
+
// Call initiateLogin directly to get OTP
|
|
25
|
+
initiateLogin(email)
|
|
26
|
+
.then(result => {
|
|
27
|
+
setOtpId(result.otpId);
|
|
28
|
+
})
|
|
29
|
+
.catch(err => {
|
|
30
|
+
console.error("Failed to initiate login:", err);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
+
}, [skipToOtp, email, step, otpId, isLoading]);
|
|
35
|
+
const handleEmailSubmit = async (e) => {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
try {
|
|
38
|
+
const result = await initiateLogin(email);
|
|
39
|
+
setOtpId(result.otpId);
|
|
40
|
+
setStep("otp");
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
// Error is handled by the hook
|
|
44
|
+
console.error("Failed to initiate login:", err);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const handleOtpSubmit = async (e) => {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
try {
|
|
50
|
+
const result = await verifyOtp(otpId, otpCode);
|
|
51
|
+
setStep("success");
|
|
52
|
+
// Auto-close after success and notify parent
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
onSuccess(result.user);
|
|
55
|
+
handleClose();
|
|
56
|
+
}, 1500);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
// Error is handled by the hook
|
|
60
|
+
console.error("Failed to verify OTP:", err);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const handleClose = () => {
|
|
64
|
+
// Reset state
|
|
65
|
+
setStep("email");
|
|
66
|
+
setEmail("");
|
|
67
|
+
setOtpCode("");
|
|
68
|
+
setOtpId("");
|
|
69
|
+
autoSubmitTriggeredRef.current = false;
|
|
70
|
+
clearError();
|
|
71
|
+
onClose();
|
|
72
|
+
};
|
|
73
|
+
const handleResendOtp = async () => {
|
|
74
|
+
try {
|
|
75
|
+
const result = await initiateLogin(email);
|
|
76
|
+
setOtpId(result.otpId);
|
|
77
|
+
clearError();
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
console.error("Failed to resend OTP:", err);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "font-neue-montreal p-8", children: [step === "email" && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("h2", { className: "mb-6 text-center text-2xl font-bold text-gray-900 dark:text-white", children: "Setup your AnySpend Wallet" }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-6 space-y-3 text-center text-sm text-gray-600 dark:text-gray-400", children: [(0, jsx_runtime_1.jsxs)("p", { children: ["AnySpend uses a secure,", (0, jsx_runtime_1.jsx)("br", {}), "embedded wallet to fund your workflows."] }), (0, jsx_runtime_1.jsxs)("p", { children: ["Please provide an email address to secure", (0, jsx_runtime_1.jsx)("br", {}), "your wallet."] })] }), (0, jsx_runtime_1.jsxs)("form", { onSubmit: handleEmailSubmit, className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("input", { type: "email", placeholder: "email", value: email, onChange: e => setEmail(e.target.value), required: true, disabled: isLoading, className: "w-full rounded-lg border border-gray-300 px-4 py-3 text-center text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 disabled:cursor-not-allowed disabled:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:placeholder-gray-500" }) }), error && ((0, jsx_runtime_1.jsx)("div", { className: "rounded-md bg-red-50 p-3 text-sm text-red-800 dark:bg-red-900/20 dark:text-red-400", children: error })), (0, jsx_runtime_1.jsx)("button", { type: "submit", disabled: isLoading || !email, className: "w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-all duration-200 hover:bg-blue-700 disabled:cursor-not-allowed disabled:bg-gray-300 dark:disabled:bg-gray-700", children: isLoading ? ((0, jsx_runtime_1.jsxs)("span", { className: "flex items-center justify-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" }), "Sending..."] })) : ("Continue") })] })] })), step === "otp" && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("h2", { className: "mb-4 text-center text-2xl font-bold text-gray-900 dark:text-white", children: "2FA Security" }), (0, jsx_runtime_1.jsx)("div", { className: "mb-6 space-y-3 text-center text-sm text-gray-600 dark:text-gray-400", children: (0, jsx_runtime_1.jsxs)("p", { children: ["AnySpend uses a secure,", (0, jsx_runtime_1.jsx)("br", {}), "embedded wallet to fund your workflows.", (0, jsx_runtime_1.jsx)("br", {}), "Please provide 2FA code sent to your email."] }) }), (0, jsx_runtime_1.jsxs)("form", { onSubmit: handleOtpSubmit, className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Enter code", value: otpCode, onChange: e => setOtpCode(e.target.value.toUpperCase()), required: true, disabled: isLoading, autoFocus: true, className: "w-full rounded-lg border border-gray-300 px-4 py-3 text-center font-mono text-lg uppercase tracking-wider text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 disabled:cursor-not-allowed disabled:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:placeholder-gray-500", maxLength: 20 }) }), error && ((0, jsx_runtime_1.jsx)("div", { className: "rounded-md bg-red-50 p-3 text-sm text-red-800 dark:bg-red-900/20 dark:text-red-400", children: error })), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-2", children: [(0, jsx_runtime_1.jsx)("button", { type: "submit", disabled: isLoading || !otpCode, className: "w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-all duration-200 hover:bg-blue-700 disabled:cursor-not-allowed disabled:bg-gray-300 dark:disabled:bg-gray-700", children: isLoading ? ((0, jsx_runtime_1.jsxs)("span", { className: "flex items-center justify-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" }), "Verifying..."] })) : ("Confirm") }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: handleResendOtp, disabled: isLoading, className: "text-sm text-blue-600 hover:text-blue-700 hover:underline disabled:cursor-not-allowed disabled:text-gray-400 dark:text-blue-400 dark:hover:text-blue-300", children: "Resend code" })] })] })] })), step === "success" && ((0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "mb-6 flex items-center justify-center", children: (0, jsx_runtime_1.jsx)("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/20", children: (0, jsx_runtime_1.jsx)("svg", { className: "h-8 w-8 text-green-600 dark:text-green-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) }) }), (0, jsx_runtime_1.jsx)("h2", { className: "mb-2 text-2xl font-bold text-gray-900 dark:text-white", children: "Successfully Authenticated!" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: "Redirecting..." })] }))] }));
|
|
84
|
+
}
|
|
@@ -12,6 +12,7 @@ export { SignInWithB3Flow } from "./SignInWithB3/SignInWithB3Flow";
|
|
|
12
12
|
export { SignInWithB3Privy } from "./SignInWithB3/SignInWithB3Privy";
|
|
13
13
|
export { LoginStepContainer } from "./SignInWithB3/steps/LoginStep";
|
|
14
14
|
export { getConnectOptionsFromStrategy, isWalletType, type AllowedStrategy } from "./SignInWithB3/utils/signInUtils";
|
|
15
|
+
export { TurnkeyAuthModal } from "./TurnkeyAuthModal";
|
|
15
16
|
export { ManageAccount } from "./ManageAccount/ManageAccount";
|
|
16
17
|
export { Deposit } from "./Deposit/Deposit";
|
|
17
18
|
export { Send } from "./Send/Send";
|
|
@@ -3,9 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.WalletImage = exports.useToastContext = exports.ToastProvider = exports.ToastContainer = void 0;
|
|
6
|
+
exports.DialogDescription = exports.DialogContent = exports.DialogClose = exports.Dialog = exports.CommandShortcut = exports.CommandSeparator = exports.CommandList = exports.CommandItem = exports.CommandInput = exports.CommandGroup = exports.CommandEmpty = exports.CommandDialog = exports.Command = exports.buttonVariants = exports.Button = exports.badgeVariants = exports.Badge = exports.WalletConnectorIcon = exports.StaggeredFadeLoader = exports.CopyToClipboard = exports.ClientOnly = exports.customButtonVariants = exports.CustomButton = exports.SendERC20Button = exports.SendETHButton = exports.MintButton = exports.AccountAssets = exports.RequestPermissionsButton = exports.RequestPermissions = exports.IPFSMediaRenderer = exports.Send = exports.Deposit = exports.ManageAccount = exports.TurnkeyAuthModal = exports.isWalletType = exports.getConnectOptionsFromStrategy = exports.LoginStepContainer = exports.SignInWithB3Privy = exports.SignInWithB3Flow = exports.SignInWithB3 = exports.WalletRow = exports.PermissionItem = exports.AuthButton = exports.StyleRoot = exports.useB3 = exports.B3Context = exports.RelayKitProviderWrapper = exports.InnerProvider = exports.B3Provider = exports.B3DynamicModal = void 0;
|
|
7
|
+
exports.toast = exports.AnimatedLottie = exports.TransitionPanel = exports.TooltipTrigger = exports.TooltipProvider = exports.TooltipContent = exports.Tooltip = exports.TextShimmer = exports.TextLoop = exports.TabTrigger = exports.TabsTransitionWrapper = exports.TabsList = exports.TabsContent = exports.Tabs = exports.TabTriggerPrimitive = exports.TabsPrimitive = exports.TabsListPrimitive = exports.TabsContentPrimitive = exports.Skeleton = exports.ShinyButton = exports.ScrollBar = exports.ScrollArea = exports.PopoverTrigger = exports.PopoverContent = exports.Popover = exports.Loading = exports.Input = exports.GlareCardRounded = exports.GlareCard = exports.DropdownMenuTrigger = exports.DropdownMenuSeparator = exports.DropdownMenuItem = exports.DropdownMenuContent = exports.DropdownMenu = exports.DrawerTrigger = exports.DrawerTitle = exports.DrawerPortal = exports.DrawerOverlay = exports.DrawerHeader = exports.DrawerFooter = exports.DrawerDescription = exports.DrawerContent = exports.DrawerClose = exports.Drawer = exports.DialogTrigger = exports.DialogTitle = exports.DialogPortal = exports.DialogOverlay = exports.DialogHeader = exports.DialogFooter = void 0;
|
|
8
|
+
exports.WalletImage = exports.useToastContext = exports.ToastProvider = exports.ToastContainer = exports.Toast = void 0;
|
|
9
9
|
// TODO woj: Barrel file for all components, this might be reason of bundle size issues
|
|
10
10
|
// Core Components
|
|
11
11
|
var B3DynamicModal_1 = require("./B3DynamicModal");
|
|
@@ -39,6 +39,9 @@ Object.defineProperty(exports, "LoginStepContainer", { enumerable: true, get: fu
|
|
|
39
39
|
var signInUtils_1 = require("./SignInWithB3/utils/signInUtils");
|
|
40
40
|
Object.defineProperty(exports, "getConnectOptionsFromStrategy", { enumerable: true, get: function () { return signInUtils_1.getConnectOptionsFromStrategy; } });
|
|
41
41
|
Object.defineProperty(exports, "isWalletType", { enumerable: true, get: function () { return signInUtils_1.isWalletType; } });
|
|
42
|
+
// Turnkey Components
|
|
43
|
+
var TurnkeyAuthModal_1 = require("./TurnkeyAuthModal");
|
|
44
|
+
Object.defineProperty(exports, "TurnkeyAuthModal", { enumerable: true, get: function () { return TurnkeyAuthModal_1.TurnkeyAuthModal; } });
|
|
42
45
|
// ManageAccount Components
|
|
43
46
|
var ManageAccount_1 = require("./ManageAccount/ManageAccount");
|
|
44
47
|
Object.defineProperty(exports, "ManageAccount", { enumerable: true, get: function () { return ManageAccount_1.ManageAccount; } });
|
|
@@ -40,5 +40,6 @@ export { useTokenFromUrl } from "./useTokenFromUrl";
|
|
|
40
40
|
export { useTokenPrice } from "./useTokenPrice";
|
|
41
41
|
export { useTokenPriceWithFallback } from "./useTokenPriceWithFallback";
|
|
42
42
|
export { useTokensFromAddress } from "./useTokensFromAddress";
|
|
43
|
+
export { useTurnkeyAuth } from "./useTurnkeyAuth";
|
|
43
44
|
export { useUnifiedChainSwitchAndExecute } from "./useUnifiedChainSwitchAndExecute";
|
|
44
45
|
export { useURLParams } from "./useURLParams";
|