@turnkey/react-wallet-kit 1.0.0-beta.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.
- package/LICENSE +201 -0
- package/README.MD +112 -0
- package/dist/_virtual/_rollupPluginBabelHelpers.mjs +420 -0
- package/dist/_virtual/_rollupPluginBabelHelpers.mjs.map +1 -0
- package/dist/components/auth/Action.d.ts +10 -0
- package/dist/components/auth/Action.d.ts.map +1 -0
- package/dist/components/auth/Action.js +76 -0
- package/dist/components/auth/Action.js.map +1 -0
- package/dist/components/auth/Action.mjs +97 -0
- package/dist/components/auth/Action.mjs.map +1 -0
- package/dist/components/auth/Email.d.ts +6 -0
- package/dist/components/auth/Email.d.ts.map +1 -0
- package/dist/components/auth/Email.js +73 -0
- package/dist/components/auth/Email.js.map +1 -0
- package/dist/components/auth/Email.mjs +95 -0
- package/dist/components/auth/Email.mjs.map +1 -0
- package/dist/components/auth/OAuth.d.ts +10 -0
- package/dist/components/auth/OAuth.d.ts.map +1 -0
- package/dist/components/auth/OAuth.js +42 -0
- package/dist/components/auth/OAuth.js.map +1 -0
- package/dist/components/auth/OAuth.mjs +46 -0
- package/dist/components/auth/OAuth.mjs.map +1 -0
- package/dist/components/auth/OTP.d.ts +19 -0
- package/dist/components/auth/OTP.d.ts.map +1 -0
- package/dist/components/auth/OTP.js +204 -0
- package/dist/components/auth/OTP.js.map +1 -0
- package/dist/components/auth/OTP.mjs +288 -0
- package/dist/components/auth/OTP.mjs.map +1 -0
- package/dist/components/auth/OrSeparator.d.ts +2 -0
- package/dist/components/auth/OrSeparator.d.ts.map +1 -0
- package/dist/components/auth/OrSeparator.js +20 -0
- package/dist/components/auth/OrSeparator.js.map +1 -0
- package/dist/components/auth/OrSeparator.mjs +18 -0
- package/dist/components/auth/OrSeparator.mjs.map +1 -0
- package/dist/components/auth/Passkey.d.ts +7 -0
- package/dist/components/auth/Passkey.d.ts.map +1 -0
- package/dist/components/auth/Passkey.js +26 -0
- package/dist/components/auth/Passkey.js.map +1 -0
- package/dist/components/auth/Passkey.mjs +22 -0
- package/dist/components/auth/Passkey.mjs.map +1 -0
- package/dist/components/auth/Phone.d.ts +6 -0
- package/dist/components/auth/Phone.d.ts.map +1 -0
- package/dist/components/auth/Phone.js +67 -0
- package/dist/components/auth/Phone.js.map +1 -0
- package/dist/components/auth/Phone.mjs +93 -0
- package/dist/components/auth/Phone.mjs.map +1 -0
- package/dist/components/auth/Wallet.d.ts +30 -0
- package/dist/components/auth/Wallet.d.ts.map +1 -0
- package/dist/components/auth/Wallet.js +408 -0
- package/dist/components/auth/Wallet.js.map +1 -0
- package/dist/components/auth/Wallet.mjs +509 -0
- package/dist/components/auth/Wallet.mjs.map +1 -0
- package/dist/components/auth/index.d.ts +2 -0
- package/dist/components/auth/index.d.ts.map +1 -0
- package/dist/components/auth/index.js +327 -0
- package/dist/components/auth/index.js.map +1 -0
- package/dist/components/auth/index.mjs +540 -0
- package/dist/components/auth/index.mjs.map +1 -0
- package/dist/components/design/Buttons.d.ts +26 -0
- package/dist/components/design/Buttons.d.ts.map +1 -0
- package/dist/components/design/Buttons.js +79 -0
- package/dist/components/design/Buttons.js.map +1 -0
- package/dist/components/design/Buttons.mjs +71 -0
- package/dist/components/design/Buttons.mjs.map +1 -0
- package/dist/components/design/Failure.d.ts +9 -0
- package/dist/components/design/Failure.d.ts.map +1 -0
- package/dist/components/design/Failure.js +33 -0
- package/dist/components/design/Failure.js.map +1 -0
- package/dist/components/design/Failure.mjs +34 -0
- package/dist/components/design/Failure.mjs.map +1 -0
- package/dist/components/design/Inputs.d.ts +9 -0
- package/dist/components/design/Inputs.d.ts.map +1 -0
- package/dist/components/design/Inputs.js +113 -0
- package/dist/components/design/Inputs.js.map +1 -0
- package/dist/components/design/Inputs.mjs +108 -0
- package/dist/components/design/Inputs.mjs.map +1 -0
- package/dist/components/design/Lottie/Dynamic.d.ts +2 -0
- package/dist/components/design/Lottie/Dynamic.d.ts.map +1 -0
- package/dist/components/design/Lottie/Dynamic.js +9 -0
- package/dist/components/design/Lottie/Dynamic.js.map +1 -0
- package/dist/components/design/Lottie/Dynamic.mjs +27 -0
- package/dist/components/design/Lottie/Dynamic.mjs.map +1 -0
- package/dist/components/design/Lottie/Wrapper.d.ts +8 -0
- package/dist/components/design/Lottie/Wrapper.d.ts.map +1 -0
- package/dist/components/design/Lottie/Wrapper.js +26 -0
- package/dist/components/design/Lottie/Wrapper.js.map +1 -0
- package/dist/components/design/Lottie/Wrapper.mjs +43 -0
- package/dist/components/design/Lottie/Wrapper.mjs.map +1 -0
- package/dist/components/design/Spinners.d.ts +9 -0
- package/dist/components/design/Spinners.d.ts.map +1 -0
- package/dist/components/design/Spinners.js +38 -0
- package/dist/components/design/Spinners.js.map +1 -0
- package/dist/components/design/Spinners.mjs +37 -0
- package/dist/components/design/Spinners.mjs.map +1 -0
- package/dist/components/design/Success.d.ts +8 -0
- package/dist/components/design/Success.d.ts.map +1 -0
- package/dist/components/design/Success.js +82 -0
- package/dist/components/design/Success.js.map +1 -0
- package/dist/components/design/Success.mjs +86 -0
- package/dist/components/design/Success.mjs.map +1 -0
- package/dist/components/design/Svg.d.ts +10 -0
- package/dist/components/design/Svg.d.ts.map +1 -0
- package/dist/components/design/Svg.js +156 -0
- package/dist/components/design/Svg.js.map +1 -0
- package/dist/components/design/Svg.mjs +153 -0
- package/dist/components/design/Svg.mjs.map +1 -0
- package/dist/components/export/Export.d.ts +9 -0
- package/dist/components/export/Export.d.ts.map +1 -0
- package/dist/components/export/Export.js +140 -0
- package/dist/components/export/Export.js.map +1 -0
- package/dist/components/export/Export.mjs +178 -0
- package/dist/components/export/Export.mjs.map +1 -0
- package/dist/components/export/ExportWarning.d.ts +12 -0
- package/dist/components/export/ExportWarning.d.ts.map +1 -0
- package/dist/components/export/ExportWarning.js +87 -0
- package/dist/components/export/ExportWarning.js.map +1 -0
- package/dist/components/export/ExportWarning.mjs +113 -0
- package/dist/components/export/ExportWarning.mjs.map +1 -0
- package/dist/components/import/Import.d.ts +14 -0
- package/dist/components/import/Import.d.ts.map +1 -0
- package/dist/components/import/Import.js +226 -0
- package/dist/components/import/Import.js.map +1 -0
- package/dist/components/import/Import.mjs +328 -0
- package/dist/components/import/Import.mjs.map +1 -0
- package/dist/components/sign/Message.d.ts +17 -0
- package/dist/components/sign/Message.d.ts.map +1 -0
- package/dist/components/sign/Message.js +127 -0
- package/dist/components/sign/Message.js.map +1 -0
- package/dist/components/sign/Message.mjs +145 -0
- package/dist/components/sign/Message.mjs.map +1 -0
- package/dist/components/user/LinkWallet.d.ts +8 -0
- package/dist/components/user/LinkWallet.d.ts.map +1 -0
- package/dist/components/user/LinkWallet.js +102 -0
- package/dist/components/user/LinkWallet.js.map +1 -0
- package/dist/components/user/LinkWallet.mjs +162 -0
- package/dist/components/user/LinkWallet.mjs.map +1 -0
- package/dist/components/user/RemoveEmail.d.ts +11 -0
- package/dist/components/user/RemoveEmail.d.ts.map +1 -0
- package/dist/components/user/RemoveEmail.js +101 -0
- package/dist/components/user/RemoveEmail.js.map +1 -0
- package/dist/components/user/RemoveEmail.mjs +122 -0
- package/dist/components/user/RemoveEmail.mjs.map +1 -0
- package/dist/components/user/RemoveOAuthProvider.d.ts +11 -0
- package/dist/components/user/RemoveOAuthProvider.d.ts.map +1 -0
- package/dist/components/user/RemoveOAuthProvider.js +106 -0
- package/dist/components/user/RemoveOAuthProvider.js.map +1 -0
- package/dist/components/user/RemoveOAuthProvider.mjs +129 -0
- package/dist/components/user/RemoveOAuthProvider.mjs.map +1 -0
- package/dist/components/user/RemovePasskey.d.ts +11 -0
- package/dist/components/user/RemovePasskey.d.ts.map +1 -0
- package/dist/components/user/RemovePasskey.js +109 -0
- package/dist/components/user/RemovePasskey.js.map +1 -0
- package/dist/components/user/RemovePasskey.mjs +132 -0
- package/dist/components/user/RemovePasskey.mjs.map +1 -0
- package/dist/components/user/RemovePhoneNumber.d.ts +11 -0
- package/dist/components/user/RemovePhoneNumber.d.ts.map +1 -0
- package/dist/components/user/RemovePhoneNumber.js +101 -0
- package/dist/components/user/RemovePhoneNumber.js.map +1 -0
- package/dist/components/user/RemovePhoneNumber.mjs +122 -0
- package/dist/components/user/RemovePhoneNumber.mjs.map +1 -0
- package/dist/components/user/UpdateEmail.d.ts +8 -0
- package/dist/components/user/UpdateEmail.d.ts.map +1 -0
- package/dist/components/user/UpdateEmail.js +139 -0
- package/dist/components/user/UpdateEmail.js.map +1 -0
- package/dist/components/user/UpdateEmail.mjs +186 -0
- package/dist/components/user/UpdateEmail.mjs.map +1 -0
- package/dist/components/user/UpdatePhoneNumber.d.ts +8 -0
- package/dist/components/user/UpdatePhoneNumber.d.ts.map +1 -0
- package/dist/components/user/UpdatePhoneNumber.js +136 -0
- package/dist/components/user/UpdatePhoneNumber.js.map +1 -0
- package/dist/components/user/UpdatePhoneNumber.mjs +187 -0
- package/dist/components/user/UpdatePhoneNumber.mjs.map +1 -0
- package/dist/components/user/UpdateUserName.d.ts +11 -0
- package/dist/components/user/UpdateUserName.d.ts.map +1 -0
- package/dist/components/user/UpdateUserName.js +112 -0
- package/dist/components/user/UpdateUserName.js.map +1 -0
- package/dist/components/user/UpdateUserName.mjs +139 -0
- package/dist/components/user/UpdateUserName.mjs.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -0
- package/dist/providers/TurnkeyProvider.d.ts +8 -0
- package/dist/providers/TurnkeyProvider.d.ts.map +1 -0
- package/dist/providers/TurnkeyProvider.js +35 -0
- package/dist/providers/TurnkeyProvider.js.map +1 -0
- package/dist/providers/TurnkeyProvider.mjs +33 -0
- package/dist/providers/TurnkeyProvider.mjs.map +1 -0
- package/dist/providers/client/Hook.d.ts +3 -0
- package/dist/providers/client/Hook.d.ts.map +1 -0
- package/dist/providers/client/Hook.js +14 -0
- package/dist/providers/client/Hook.js.map +1 -0
- package/dist/providers/client/Hook.mjs +12 -0
- package/dist/providers/client/Hook.mjs.map +1 -0
- package/dist/providers/client/Provider.d.ts +39 -0
- package/dist/providers/client/Provider.d.ts.map +1 -0
- package/dist/providers/client/Provider.js +2489 -0
- package/dist/providers/client/Provider.js.map +1 -0
- package/dist/providers/client/Provider.mjs +4744 -0
- package/dist/providers/client/Provider.mjs.map +1 -0
- package/dist/providers/client/Types.d.ts +524 -0
- package/dist/providers/client/Types.d.ts.map +1 -0
- package/dist/providers/client/Types.js +9 -0
- package/dist/providers/client/Types.js.map +1 -0
- package/dist/providers/client/Types.mjs +7 -0
- package/dist/providers/client/Types.mjs.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/modal/Hook.d.ts +3 -0
- package/dist/providers/modal/Hook.d.ts.map +1 -0
- package/dist/providers/modal/Hook.js +14 -0
- package/dist/providers/modal/Hook.js.map +1 -0
- package/dist/providers/modal/Hook.mjs +12 -0
- package/dist/providers/modal/Hook.mjs.map +1 -0
- package/dist/providers/modal/Provider.d.ts +21 -0
- package/dist/providers/modal/Provider.d.ts.map +1 -0
- package/dist/providers/modal/Provider.js +37 -0
- package/dist/providers/modal/Provider.js.map +1 -0
- package/dist/providers/modal/Provider.mjs +48 -0
- package/dist/providers/modal/Provider.mjs.map +1 -0
- package/dist/providers/modal/Root.d.ts +7 -0
- package/dist/providers/modal/Root.d.ts.map +1 -0
- package/dist/providers/modal/Root.js +258 -0
- package/dist/providers/modal/Root.js.map +1 -0
- package/dist/providers/modal/Root.mjs +263 -0
- package/dist/providers/modal/Root.mjs.map +1 -0
- package/dist/providers/theme/Overrides.d.ts +18 -0
- package/dist/providers/theme/Overrides.d.ts.map +1 -0
- package/dist/providers/theme/Overrides.js +35 -0
- package/dist/providers/theme/Overrides.js.map +1 -0
- package/dist/providers/theme/Overrides.mjs +37 -0
- package/dist/providers/theme/Overrides.mjs.map +1 -0
- package/dist/styles.css +1 -0
- package/dist/types/base.d.ts +79 -0
- package/dist/types/base.d.ts.map +1 -0
- package/dist/types/base.js +19 -0
- package/dist/types/base.js.map +1 -0
- package/dist/types/base.mjs +19 -0
- package/dist/types/base.mjs.map +1 -0
- package/dist/utils.d.ts +72 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +211 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +307 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,2489 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var sha2 = require('@noble/hashes/sha2');
|
|
6
|
+
var utils$1 = require('@noble/hashes/utils');
|
|
7
|
+
var utils = require('../../utils.js');
|
|
8
|
+
var core = require('@turnkey/core');
|
|
9
|
+
var react = require('react');
|
|
10
|
+
var sdkTypes = require('@turnkey/sdk-types');
|
|
11
|
+
var Hook = require('../modal/Hook.js');
|
|
12
|
+
var base = require('../../types/base.js');
|
|
13
|
+
var index = require('../../components/auth/index.js');
|
|
14
|
+
var reactFontawesome = require('@fortawesome/react-fontawesome');
|
|
15
|
+
var freeBrandsSvgIcons = require('@fortawesome/free-brands-svg-icons');
|
|
16
|
+
var Action = require('../../components/auth/Action.js');
|
|
17
|
+
var Message = require('../../components/sign/Message.js');
|
|
18
|
+
var Export = require('../../components/export/Export.js');
|
|
19
|
+
var Import = require('../../components/import/Import.js');
|
|
20
|
+
var Success = require('../../components/design/Success.js');
|
|
21
|
+
var UpdateEmail = require('../../components/user/UpdateEmail.js');
|
|
22
|
+
var UpdatePhoneNumber = require('../../components/user/UpdatePhoneNumber.js');
|
|
23
|
+
var UpdateUserName = require('../../components/user/UpdateUserName.js');
|
|
24
|
+
var RemoveOAuthProvider = require('../../components/user/RemoveOAuthProvider.js');
|
|
25
|
+
var RemovePasskey = require('../../components/user/RemovePasskey.js');
|
|
26
|
+
var LinkWallet = require('../../components/user/LinkWallet.js');
|
|
27
|
+
var Types = require('./Types.js');
|
|
28
|
+
var OTP = require('../../components/auth/OTP.js');
|
|
29
|
+
var RemoveEmail = require('../../components/user/RemoveEmail.js');
|
|
30
|
+
var RemovePhoneNumber = require('../../components/user/RemovePhoneNumber.js');
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Provides Turnkey client authentication, session management, wallet operations, and user profile management
|
|
34
|
+
* for the React Wallet Kit SDK. This context provider encapsulates all core authentication flows (Passkey, Wallet, OTP, OAuth),
|
|
35
|
+
* session lifecycle (creation, expiration, refresh), wallet linking/import/export, and user profile updates (email, phone, name).
|
|
36
|
+
*
|
|
37
|
+
* The provider automatically initializes the Turnkey client, fetches configuration (including proxy auth config if needed),
|
|
38
|
+
* and synchronizes session and authentication state. It exposes a comprehensive set of methods for authentication flows,
|
|
39
|
+
* wallet management, and user profile operations, as well as UI handlers for modal-driven flows.
|
|
40
|
+
*
|
|
41
|
+
* Features:
|
|
42
|
+
* - Passkey, Wallet, OTP (Email/SMS), and OAuth (Google, Apple, Facebook) authentication and sign-up flows.
|
|
43
|
+
* - Session management: creation, expiration scheduling, refresh, and clearing.
|
|
44
|
+
* - Wallet management: fetch, link, import, export, account management.
|
|
45
|
+
* - User profile management: email, phone, name, OAuth provider, and passkey linking/removal.
|
|
46
|
+
* - Modal-driven UI flows for authentication, wallet linking, and profile updates.
|
|
47
|
+
* - Error handling and callback integration for custom error and event responses.
|
|
48
|
+
*
|
|
49
|
+
* Usage:
|
|
50
|
+
* Wrap your application with `TurnkeyProvider` to enable authentication and wallet features via context.
|
|
51
|
+
*
|
|
52
|
+
* @param config - The Turnkey provider configuration object.
|
|
53
|
+
* @param children - React children to be rendered within the provider.
|
|
54
|
+
* @param callbacks - Optional callbacks for error handling and session events.
|
|
55
|
+
*
|
|
56
|
+
* @returns A React context provider exposing authentication, wallet, and user management methods and state.
|
|
57
|
+
*/
|
|
58
|
+
const ClientProvider = ({
|
|
59
|
+
config,
|
|
60
|
+
children,
|
|
61
|
+
callbacks
|
|
62
|
+
}) => {
|
|
63
|
+
const [client, setClient] = react.useState(undefined);
|
|
64
|
+
const [session, setSession] = react.useState(undefined);
|
|
65
|
+
const [autoRefreshSession, setAutoRefreshSession] = react.useState(false);
|
|
66
|
+
const [masterConfig, setMasterConfig] = react.useState(undefined);
|
|
67
|
+
const [wallets, setWallets] = react.useState([]);
|
|
68
|
+
const [user, setUser] = react.useState(undefined);
|
|
69
|
+
const [clientState, setClientState] = react.useState();
|
|
70
|
+
const [authState, setAuthState] = react.useState(base.AuthState.Unauthenticated);
|
|
71
|
+
const expiryTimeoutsRef = react.useRef({});
|
|
72
|
+
const proxyAuthConfigRef = react.useRef(null);
|
|
73
|
+
const [allSessions, setAllSessions] = react.useState(undefined);
|
|
74
|
+
const {
|
|
75
|
+
pushPage,
|
|
76
|
+
closeModal
|
|
77
|
+
} = Hook.useModal();
|
|
78
|
+
react.useEffect(() => {
|
|
79
|
+
if (proxyAuthConfigRef.current) return;
|
|
80
|
+
// Only fetch the proxy auth config once. Use that to build the master config.
|
|
81
|
+
const fetchProxyAuthConfig = async () => {
|
|
82
|
+
try {
|
|
83
|
+
let proxyAuthConfig;
|
|
84
|
+
if (config.authProxyConfigId) {
|
|
85
|
+
// Only fetch the proxy auth config if we have an authProxyId. This is a way for devs to explicitly disable the proxy auth.
|
|
86
|
+
proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId, config.authProxyUrl);
|
|
87
|
+
proxyAuthConfigRef.current = proxyAuthConfig;
|
|
88
|
+
}
|
|
89
|
+
setMasterConfig(buildConfig(proxyAuthConfig));
|
|
90
|
+
} catch {
|
|
91
|
+
setClientState(base.ClientState.Error);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
fetchProxyAuthConfig();
|
|
95
|
+
}, []);
|
|
96
|
+
react.useEffect(() => {
|
|
97
|
+
// Start the client initialization process once we have the master config.
|
|
98
|
+
if (!masterConfig) return;
|
|
99
|
+
initializeClient();
|
|
100
|
+
}, [masterConfig]);
|
|
101
|
+
react.useEffect(() => {
|
|
102
|
+
// Handle changes to the passed in config prop -- update the master config
|
|
103
|
+
// If the proxyAuthConfigRef is already set, we don't need to fetch it again. Rebuild the master config with the updated config and stored proxyAuthConfig
|
|
104
|
+
if (!proxyAuthConfigRef.current && config.authProxyConfigId) return;
|
|
105
|
+
setMasterConfig(buildConfig(proxyAuthConfigRef.current ?? undefined));
|
|
106
|
+
}, [config, proxyAuthConfigRef.current]);
|
|
107
|
+
/**
|
|
108
|
+
* @internal
|
|
109
|
+
* we use debouncedFetchWallets() to prevent multiple rapid wallet events
|
|
110
|
+
* like accountsChanged and disconnect from triggering fetchWallets repeatedly
|
|
111
|
+
* it must be defined outside the useEffect so all event listeners share the same
|
|
112
|
+
* debounced function instance - otherwise, a new one would be created on every render
|
|
113
|
+
*/
|
|
114
|
+
const debouncedFetchWallets = utils.useDebouncedCallback(fetchWallets, 100);
|
|
115
|
+
react.useEffect(() => {
|
|
116
|
+
if (!client) return;
|
|
117
|
+
let cleanup = () => {};
|
|
118
|
+
initializeProviders(getWalletProviders, debouncedFetchWallets).then(fn => {
|
|
119
|
+
cleanup = fn;
|
|
120
|
+
}).catch(err => {
|
|
121
|
+
console.error("Failed to init providers:", err);
|
|
122
|
+
});
|
|
123
|
+
return () => {
|
|
124
|
+
cleanup();
|
|
125
|
+
};
|
|
126
|
+
}, [client, debouncedFetchWallets]);
|
|
127
|
+
react.useEffect(() => {
|
|
128
|
+
// authState must be consistent with session state. We found during testing that there are cases where the session and authState can be out of sync in very rare edge cases.
|
|
129
|
+
// This will ensure that they are always in sync and remove the need to setAuthState manually in other places.
|
|
130
|
+
if (session) {
|
|
131
|
+
setAuthState(base.AuthState.Authenticated);
|
|
132
|
+
} else {
|
|
133
|
+
setAuthState(base.AuthState.Unauthenticated);
|
|
134
|
+
}
|
|
135
|
+
}, [session]);
|
|
136
|
+
react.useEffect(() => {
|
|
137
|
+
// This will handle any redirect based oAuth. It then initializes the session. This is the last step before client is considered "ready"
|
|
138
|
+
if (!client || !masterConfig) return;
|
|
139
|
+
completeRedirectOauth().finally(() => {
|
|
140
|
+
clearSessionTimeouts();
|
|
141
|
+
initializeSessions().finally(() => {
|
|
142
|
+
// Set the client state to ready only after all initializations are done.
|
|
143
|
+
setClientState(base.ClientState.Ready);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
return () => {
|
|
147
|
+
clearSessionTimeouts();
|
|
148
|
+
};
|
|
149
|
+
}, [client]);
|
|
150
|
+
const completeRedirectOauth = async () => {
|
|
151
|
+
// Check for either hash or search parameters that could indicate an OAuth redirect
|
|
152
|
+
if (window.location.hash || window.location.search) {
|
|
153
|
+
// Handle Facebook redirect (uses search params with code)
|
|
154
|
+
if (window.location.search && window.location.search.includes("code=") && window.location.search.includes("state=")) {
|
|
155
|
+
const searchParams = new URLSearchParams(window.location.search.substring(1));
|
|
156
|
+
const code = searchParams.get("code");
|
|
157
|
+
const state = searchParams.get("state");
|
|
158
|
+
// Parse state parameter
|
|
159
|
+
if (state && code) {
|
|
160
|
+
const stateParams = new URLSearchParams(state);
|
|
161
|
+
const provider = stateParams.get("provider");
|
|
162
|
+
const flow = stateParams.get("flow");
|
|
163
|
+
const publicKey = stateParams.get("publicKey");
|
|
164
|
+
const openModal = stateParams.get("openModal");
|
|
165
|
+
if (provider === "facebook" && flow === "redirect" && publicKey) {
|
|
166
|
+
// We have all the required parameters for a Facebook PKCE flow
|
|
167
|
+
const clientId = masterConfig?.auth?.oauthConfig?.facebookClientId;
|
|
168
|
+
const redirectURI = masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
|
|
169
|
+
if (clientId && redirectURI) {
|
|
170
|
+
await utils.handleFacebookPKCEFlow({
|
|
171
|
+
code,
|
|
172
|
+
publicKey,
|
|
173
|
+
openModal,
|
|
174
|
+
clientId,
|
|
175
|
+
redirectURI,
|
|
176
|
+
callbacks,
|
|
177
|
+
completeOauth,
|
|
178
|
+
onPushPage: oidcToken => {
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
pushPage({
|
|
181
|
+
key: `Facebook OAuth`,
|
|
182
|
+
content: jsxRuntime.jsx(Action.ActionPage, {
|
|
183
|
+
title: `Authenticating with Facebook...`,
|
|
184
|
+
action: async () => {
|
|
185
|
+
try {
|
|
186
|
+
await completeOauth({
|
|
187
|
+
oidcToken,
|
|
188
|
+
publicKey,
|
|
189
|
+
providerName: "facebook"
|
|
190
|
+
});
|
|
191
|
+
resolve();
|
|
192
|
+
} catch (err) {
|
|
193
|
+
reject(err);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, {
|
|
197
|
+
size: "3x",
|
|
198
|
+
icon: freeBrandsSvgIcons.faFacebook
|
|
199
|
+
})
|
|
200
|
+
}),
|
|
201
|
+
showTitle: false
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}).catch(error => {
|
|
206
|
+
// Handle errors
|
|
207
|
+
if (callbacks?.onError) {
|
|
208
|
+
callbacks.onError(error instanceof sdkTypes.TurnkeyError ? error : new sdkTypes.TurnkeyError("Facebook authentication failed", sdkTypes.TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR, error));
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Handle Google/Apple redirects (uses hash with id_token)
|
|
216
|
+
else if (window.location.hash) {
|
|
217
|
+
const hash = window.location.hash.substring(1);
|
|
218
|
+
// Parse the hash using our helper functions
|
|
219
|
+
const {
|
|
220
|
+
idToken,
|
|
221
|
+
provider,
|
|
222
|
+
flow,
|
|
223
|
+
publicKey,
|
|
224
|
+
openModal
|
|
225
|
+
} = utils.parseOAuthRedirect(hash);
|
|
226
|
+
if (idToken && flow === "redirect" && publicKey) {
|
|
227
|
+
if (openModal === "true") {
|
|
228
|
+
const providerName = provider ? provider.charAt(0).toUpperCase() + provider.slice(1) : "Provider";
|
|
229
|
+
// Determine which icon to show based on the provider
|
|
230
|
+
let icon;
|
|
231
|
+
if (provider === "apple") {
|
|
232
|
+
icon = jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, {
|
|
233
|
+
size: "3x",
|
|
234
|
+
icon: freeBrandsSvgIcons.faApple
|
|
235
|
+
});
|
|
236
|
+
} else {
|
|
237
|
+
// Default to Google icon
|
|
238
|
+
icon = jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, {
|
|
239
|
+
size: "3x",
|
|
240
|
+
icon: freeBrandsSvgIcons.faGoogle
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
// This state is set when the OAuth flow comes from the AuthComponent
|
|
244
|
+
await new Promise((resolve, reject) => {
|
|
245
|
+
pushPage({
|
|
246
|
+
key: `${providerName} OAuth`,
|
|
247
|
+
content: jsxRuntime.jsx(Action.ActionPage, {
|
|
248
|
+
title: `Authenticating with ${providerName}...`,
|
|
249
|
+
action: async () => {
|
|
250
|
+
try {
|
|
251
|
+
await completeOauth({
|
|
252
|
+
oidcToken: idToken,
|
|
253
|
+
publicKey,
|
|
254
|
+
...(provider ? {
|
|
255
|
+
providerName: provider
|
|
256
|
+
} : {})
|
|
257
|
+
});
|
|
258
|
+
resolve(null);
|
|
259
|
+
} catch (err) {
|
|
260
|
+
reject(err);
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
icon: icon
|
|
264
|
+
}),
|
|
265
|
+
showTitle: false
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
} else if (callbacks?.onOauthRedirect) {
|
|
269
|
+
callbacks.onOauthRedirect({
|
|
270
|
+
idToken,
|
|
271
|
+
publicKey
|
|
272
|
+
});
|
|
273
|
+
} else {
|
|
274
|
+
completeOauth({
|
|
275
|
+
oidcToken: idToken,
|
|
276
|
+
publicKey,
|
|
277
|
+
...(provider ? {
|
|
278
|
+
providerName: provider
|
|
279
|
+
} : {})
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
// Clean up the URL after processing
|
|
283
|
+
window.history.replaceState(null, document.title, window.location.pathname + window.location.search);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
const buildConfig = proxyAuthConfig => {
|
|
289
|
+
// Juggle the local overrides with the values set in the dashboard (proxyAuthConfig).
|
|
290
|
+
const resolvedMethods = {
|
|
291
|
+
emailOtpAuthEnabled: config.auth?.methods?.emailOtpAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("email"),
|
|
292
|
+
smsOtpAuthEnabled: config.auth?.methods?.smsOtpAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("sms"),
|
|
293
|
+
passkeyAuthEnabled: config.auth?.methods?.passkeyAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("passkey"),
|
|
294
|
+
walletAuthEnabled: config.auth?.methods?.walletAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("wallet"),
|
|
295
|
+
googleOauthEnabled: config.auth?.methods?.googleOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("google"),
|
|
296
|
+
appleOauthEnabled: config.auth?.methods?.appleOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("apple"),
|
|
297
|
+
facebookOauthEnabled: config.auth?.methods?.facebookOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("facebook")
|
|
298
|
+
};
|
|
299
|
+
// Set a default ordering for the oAuth methods
|
|
300
|
+
const oauthOrder = config.auth?.oauthOrder ?? ["google", "apple", "facebook"].filter(provider => resolvedMethods[`${provider}OauthEnabled`]);
|
|
301
|
+
// Set a default ordering for the overall auth methods
|
|
302
|
+
const methodOrder = config.auth?.methodOrder ?? [oauthOrder.length > 0 ? "socials" : null, resolvedMethods.emailOtpAuthEnabled ? "email" : null, resolvedMethods.smsOtpAuthEnabled ? "sms" : null, resolvedMethods.passkeyAuthEnabled ? "passkey" : null, resolvedMethods.walletAuthEnabled ? "wallet" : null].filter(Boolean);
|
|
303
|
+
return {
|
|
304
|
+
...config,
|
|
305
|
+
// Overrides:
|
|
306
|
+
auth: {
|
|
307
|
+
...config.auth,
|
|
308
|
+
methods: resolvedMethods,
|
|
309
|
+
oauthConfig: {
|
|
310
|
+
...config.auth?.oauthConfig,
|
|
311
|
+
openOauthInPage: config.auth?.oauthConfig?.openOauthInPage
|
|
312
|
+
},
|
|
313
|
+
sessionExpirationSeconds: proxyAuthConfig?.sessionExpirationSeconds,
|
|
314
|
+
methodOrder,
|
|
315
|
+
oauthOrder
|
|
316
|
+
},
|
|
317
|
+
walletConfig: {
|
|
318
|
+
...config.walletConfig,
|
|
319
|
+
features: {
|
|
320
|
+
...config.walletConfig?.features,
|
|
321
|
+
auth:
|
|
322
|
+
// If walletAuthEnabled is not set, default to true. Wallet auth can be enabled/disabled in the dashboard or by explicitly changing the walletAuthEnabled / walletConfig auth feature.
|
|
323
|
+
resolvedMethods.walletAuthEnabled ?? config.walletConfig?.features?.auth ?? true,
|
|
324
|
+
connecting: config.walletConfig?.features?.connecting ?? true // Default connecting to true if not set. We don't care about auth settings here.
|
|
325
|
+
},
|
|
326
|
+
chains: {
|
|
327
|
+
...config.walletConfig?.chains,
|
|
328
|
+
ethereum: {
|
|
329
|
+
...config.walletConfig?.chains?.ethereum,
|
|
330
|
+
native: true // Always enable native Ethereum support
|
|
331
|
+
},
|
|
332
|
+
solana: {
|
|
333
|
+
...config.walletConfig?.chains?.solana,
|
|
334
|
+
native: true // Always enable native Solana support
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
importIframeUrl: config.importIframeUrl ?? "https://import.turnkey.com",
|
|
339
|
+
exportIframeUrl: config.exportIframeUrl ?? "https://export.turnkey.com"
|
|
340
|
+
};
|
|
341
|
+
};
|
|
342
|
+
/**
|
|
343
|
+
* Initializes the Turnkey client with the provided configuration.
|
|
344
|
+
* This function sets up the client, fetches the proxy auth config if needed,
|
|
345
|
+
* and prepares the client for use in authentication and wallet operations.
|
|
346
|
+
*
|
|
347
|
+
* @internal
|
|
348
|
+
*/
|
|
349
|
+
const initializeClient = async () => {
|
|
350
|
+
if (!masterConfig || client || clientState == base.ClientState.Loading) return;
|
|
351
|
+
try {
|
|
352
|
+
setClientState(base.ClientState.Loading);
|
|
353
|
+
const turnkeyClient = new core.TurnkeyClient({
|
|
354
|
+
apiBaseUrl: masterConfig.apiBaseUrl,
|
|
355
|
+
authProxyUrl: masterConfig.authProxyUrl,
|
|
356
|
+
authProxyConfigId: masterConfig.authProxyConfigId,
|
|
357
|
+
organizationId: masterConfig.organizationId,
|
|
358
|
+
// Define passkey and wallet config here. If we don't pass it into the client, Mr. Client will assume that we don't want to use passkeys/wallets and not create the stamper!
|
|
359
|
+
passkeyConfig: {
|
|
360
|
+
rpId: masterConfig.passkeyConfig?.rpId,
|
|
361
|
+
timeout: masterConfig.passkeyConfig?.timeout || 60000,
|
|
362
|
+
// 60 seconds
|
|
363
|
+
userVerification: masterConfig.passkeyConfig?.userVerification || "preferred",
|
|
364
|
+
allowCredentials: masterConfig.passkeyConfig?.allowCredentials || []
|
|
365
|
+
},
|
|
366
|
+
walletConfig: {
|
|
367
|
+
features: {
|
|
368
|
+
...masterConfig.walletConfig?.features
|
|
369
|
+
},
|
|
370
|
+
chains: {
|
|
371
|
+
...masterConfig.walletConfig?.chains
|
|
372
|
+
},
|
|
373
|
+
...(masterConfig.walletConfig?.walletConnect && {
|
|
374
|
+
walletConnect: masterConfig.walletConfig.walletConnect
|
|
375
|
+
})
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
setAutoRefreshSession(masterConfig?.auth?.autoRefreshSession ?? false);
|
|
379
|
+
await turnkeyClient.init();
|
|
380
|
+
setClient(turnkeyClient);
|
|
381
|
+
// Don't set clientState to ready until we fetch the proxy auth config (See other fetchProxyAuthConfig useEffect)
|
|
382
|
+
} catch (error) {
|
|
383
|
+
setClientState(base.ClientState.Error);
|
|
384
|
+
if (error instanceof sdkTypes.TurnkeyError || error instanceof sdkTypes.TurnkeyNetworkError) {
|
|
385
|
+
callbacks?.onError?.(error);
|
|
386
|
+
} else {
|
|
387
|
+
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to initialize Turnkey client`, sdkTypes.TurnkeyErrorCodes.INITIALIZE_CLIENT_ERROR, error));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
/**
|
|
392
|
+
* Initializes the user sessions by fetching all active sessions and setting up their state.
|
|
393
|
+
* @internal
|
|
394
|
+
*/
|
|
395
|
+
const initializeSessions = async () => {
|
|
396
|
+
try {
|
|
397
|
+
const allSessions = await getAllSessions();
|
|
398
|
+
if (!allSessions) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
await Promise.all(Object.keys(allSessions).map(async sessionKey => {
|
|
402
|
+
const session = allSessions?.[sessionKey];
|
|
403
|
+
if (!utils.isValidSession(session)) {
|
|
404
|
+
await clearSession({
|
|
405
|
+
sessionKey
|
|
406
|
+
});
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
scheduleSessionExpiration({
|
|
410
|
+
sessionKey,
|
|
411
|
+
expiry: session.expiry
|
|
412
|
+
});
|
|
413
|
+
}));
|
|
414
|
+
setAllSessions(allSessions);
|
|
415
|
+
const activeSessionKey = await client?.getActiveSessionKey();
|
|
416
|
+
if (activeSessionKey) {
|
|
417
|
+
setSession(allSessions?.[activeSessionKey]);
|
|
418
|
+
await refreshUser();
|
|
419
|
+
await refreshWallets();
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
} catch (error) {
|
|
423
|
+
if (error instanceof sdkTypes.TurnkeyError || error instanceof sdkTypes.TurnkeyNetworkError) {
|
|
424
|
+
callbacks?.onError?.(error);
|
|
425
|
+
} else {
|
|
426
|
+
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to initialize sessions`, sdkTypes.TurnkeyErrorCodes.INITIALIZE_SESSION_ERROR, error));
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
/**
|
|
431
|
+
* @internal
|
|
432
|
+
* Schedules a session expiration and warning timeout for the given session key.
|
|
433
|
+
*
|
|
434
|
+
* - This function sets up two timeouts: one for warning before the session expires and another to expire the session.
|
|
435
|
+
* - The warning timeout is set to trigger before the session expires, allowing for actions like refreshing the session.
|
|
436
|
+
* - The expiration timeout clears the session and triggers any necessary callbacks.
|
|
437
|
+
*
|
|
438
|
+
* @param params.sessionKey - The key of the session to schedule expiration for.
|
|
439
|
+
* @param params.expiry - The expiration time in seconds for the session.
|
|
440
|
+
* @throws {TurnkeyError} If an error occurs while scheduling the session expiration.
|
|
441
|
+
*/
|
|
442
|
+
async function scheduleSessionExpiration(params) {
|
|
443
|
+
const {
|
|
444
|
+
sessionKey,
|
|
445
|
+
expiry
|
|
446
|
+
} = params;
|
|
447
|
+
try {
|
|
448
|
+
// Clear any existing timeout for this session key
|
|
449
|
+
if (expiryTimeoutsRef.current[sessionKey]) {
|
|
450
|
+
clearTimeout(expiryTimeoutsRef.current[sessionKey]);
|
|
451
|
+
delete expiryTimeoutsRef.current[sessionKey];
|
|
452
|
+
}
|
|
453
|
+
if (expiryTimeoutsRef.current[`${sessionKey}-warning`]) {
|
|
454
|
+
clearTimeout(expiryTimeoutsRef.current[`${sessionKey}-warning`]);
|
|
455
|
+
delete expiryTimeoutsRef.current[`${sessionKey}-warning`];
|
|
456
|
+
}
|
|
457
|
+
const timeUntilExpiry = expiry * 1000 - Date.now();
|
|
458
|
+
const beforeExpiry = async () => {
|
|
459
|
+
const activeSession = await getSession();
|
|
460
|
+
if (!activeSession && expiryTimeoutsRef.current[sessionKey]) {
|
|
461
|
+
clearTimeout(expiryTimeoutsRef.current[`${sessionKey}-warning`]);
|
|
462
|
+
expiryTimeoutsRef.current[`${sessionKey}-warning`] = setTimeout(beforeExpiry, 10000);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
const session = await getSession({
|
|
466
|
+
sessionKey
|
|
467
|
+
});
|
|
468
|
+
if (!session) return;
|
|
469
|
+
callbacks?.beforeSessionExpiry?.({
|
|
470
|
+
sessionKey
|
|
471
|
+
});
|
|
472
|
+
if (autoRefreshSession) {
|
|
473
|
+
await refreshSession({
|
|
474
|
+
expirationSeconds: session.expirationSeconds,
|
|
475
|
+
sessionKey
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
const expireSession = async () => {
|
|
480
|
+
const expiredSession = await getSession({
|
|
481
|
+
sessionKey
|
|
482
|
+
});
|
|
483
|
+
if (!expiredSession) return;
|
|
484
|
+
callbacks?.onSessionExpired?.({
|
|
485
|
+
sessionKey
|
|
486
|
+
});
|
|
487
|
+
await clearSession({
|
|
488
|
+
sessionKey
|
|
489
|
+
});
|
|
490
|
+
delete expiryTimeoutsRef.current[sessionKey];
|
|
491
|
+
delete expiryTimeoutsRef.current[`${sessionKey}-warning`];
|
|
492
|
+
await logout();
|
|
493
|
+
};
|
|
494
|
+
if (timeUntilExpiry <= utils.SESSION_WARNING_THRESHOLD_MS) {
|
|
495
|
+
beforeExpiry();
|
|
496
|
+
} else {
|
|
497
|
+
expiryTimeoutsRef.current[`${sessionKey}-warning`] = setTimeout(beforeExpiry, timeUntilExpiry - utils.SESSION_WARNING_THRESHOLD_MS);
|
|
498
|
+
}
|
|
499
|
+
expiryTimeoutsRef.current[sessionKey] = setTimeout(expireSession, timeUntilExpiry);
|
|
500
|
+
} catch (error) {
|
|
501
|
+
if (error instanceof sdkTypes.TurnkeyError || error instanceof sdkTypes.TurnkeyNetworkError) {
|
|
502
|
+
callbacks?.onError?.(error);
|
|
503
|
+
} else {
|
|
504
|
+
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to schedule session expiration for ${sessionKey}`, sdkTypes.TurnkeyErrorCodes.SCHEDULE_SESSION_EXPIRY_ERROR, error));
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Clears all scheduled session expiration and warning timeouts for the client.
|
|
510
|
+
*
|
|
511
|
+
* - This function removes all active session expiration and warning timeouts managed by the provider.
|
|
512
|
+
* - It is called automatically when sessions are re-initialized or on logout to prevent memory leaks and ensure no stale timeouts remain.
|
|
513
|
+
* - All timeouts stored in `expiryTimeoutsRef` are cleared and the reference is reset.
|
|
514
|
+
*
|
|
515
|
+
* @throws {TurnkeyError} If an error occurs while clearing the timeouts.
|
|
516
|
+
*/
|
|
517
|
+
function clearSessionTimeouts() {
|
|
518
|
+
try {
|
|
519
|
+
Object.values(expiryTimeoutsRef.current).forEach(timeout => {
|
|
520
|
+
clearTimeout(timeout);
|
|
521
|
+
});
|
|
522
|
+
expiryTimeoutsRef.current = {};
|
|
523
|
+
} catch (error) {
|
|
524
|
+
if (error instanceof sdkTypes.TurnkeyError || error instanceof sdkTypes.TurnkeyNetworkError) {
|
|
525
|
+
callbacks?.onError?.(error);
|
|
526
|
+
} else {
|
|
527
|
+
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to clear session timeouts`, sdkTypes.TurnkeyErrorCodes.CLEAR_SESSION_TIMEOUTS_ERROR, error));
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* @internal
|
|
533
|
+
* Handles the post-authentication flow.
|
|
534
|
+
*
|
|
535
|
+
* - This function is called after a successful authentication (login or sign-up) via any supported method (Passkey, Wallet, OTP, OAuth).
|
|
536
|
+
* - It fetches the active session and all sessions, updates the session state, and schedules session expiration and warning timeouts.
|
|
537
|
+
* - It also refreshes the user's wallets and profile information to ensure the provider state is up to date.
|
|
538
|
+
* - This function is used internally after all authentication flows to synchronize state and trigger any necessary callbacks.
|
|
539
|
+
*
|
|
540
|
+
* @returns A void promise.
|
|
541
|
+
* @throws {TurnkeyError} If the client is not initialized or if there is an error during the process.
|
|
542
|
+
*/
|
|
543
|
+
const handlePostAuth = async () => {
|
|
544
|
+
try {
|
|
545
|
+
const sessionKey = await getActiveSessionKey();
|
|
546
|
+
const session = await getSession({
|
|
547
|
+
...(sessionKey && {
|
|
548
|
+
sessionKey
|
|
549
|
+
})
|
|
550
|
+
});
|
|
551
|
+
if (session && sessionKey) await scheduleSessionExpiration({
|
|
552
|
+
sessionKey,
|
|
553
|
+
expiry: session.expiry
|
|
554
|
+
});
|
|
555
|
+
const allSessions = await client.getAllSessions();
|
|
556
|
+
setSession(session);
|
|
557
|
+
setAllSessions(allSessions);
|
|
558
|
+
await refreshWallets();
|
|
559
|
+
await refreshUser();
|
|
560
|
+
} catch (error) {
|
|
561
|
+
if (error instanceof sdkTypes.TurnkeyError || error instanceof sdkTypes.TurnkeyNetworkError) {
|
|
562
|
+
callbacks?.onError?.(error);
|
|
563
|
+
} else {
|
|
564
|
+
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to handle post-authentication`, sdkTypes.TurnkeyErrorCodes.HANDLE_POST_AUTH_ERROR, error));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
/**
|
|
569
|
+
* @internal
|
|
570
|
+
* Handles the post-logout flow.
|
|
571
|
+
*
|
|
572
|
+
* - This function is called after a successful logout or session clear.
|
|
573
|
+
* - It clears all scheduled session expiration and warning timeouts to prevent memory leaks.
|
|
574
|
+
* - It resets the session state, removes all session and user data from memory, and clears the wallets list.
|
|
575
|
+
* - This ensures that all sensitive information is removed from the provider state after logout.
|
|
576
|
+
* - Called internally after logout or when all sessions are cleared.
|
|
577
|
+
*
|
|
578
|
+
* @returns void
|
|
579
|
+
* @throws {TurnkeyError} If there is an error during the post-logout process.
|
|
580
|
+
*/
|
|
581
|
+
const handlePostLogout = () => {
|
|
582
|
+
try {
|
|
583
|
+
clearSessionTimeouts();
|
|
584
|
+
setSession(undefined);
|
|
585
|
+
setAllSessions(undefined);
|
|
586
|
+
setUser(undefined);
|
|
587
|
+
setWallets([]);
|
|
588
|
+
} catch (error) {
|
|
589
|
+
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to initialize sessions`, sdkTypes.TurnkeyErrorCodes.HANDLE_POST_LOGOUT_ERROR, error));
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
async function createPasskey(params) {
|
|
593
|
+
if (!client) {
|
|
594
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
595
|
+
}
|
|
596
|
+
return utils.withTurnkeyErrorHandling(() => client.createPasskey({
|
|
597
|
+
...params
|
|
598
|
+
}), callbacks, "Failed to create passkey");
|
|
599
|
+
}
|
|
600
|
+
async function logout(params) {
|
|
601
|
+
if (!client) {
|
|
602
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
603
|
+
}
|
|
604
|
+
utils.withTurnkeyErrorHandling(() => client.logout(params), callbacks, "Failed to logout");
|
|
605
|
+
handlePostLogout();
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
async function loginWithPasskey(params) {
|
|
609
|
+
if (!client) {
|
|
610
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
611
|
+
}
|
|
612
|
+
const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
613
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.loginWithPasskey({
|
|
614
|
+
...params,
|
|
615
|
+
expirationSeconds
|
|
616
|
+
}), callbacks, "Failed to login with passkey");
|
|
617
|
+
if (res) {
|
|
618
|
+
await handlePostAuth();
|
|
619
|
+
}
|
|
620
|
+
return res;
|
|
621
|
+
}
|
|
622
|
+
async function signUpWithPasskey(params) {
|
|
623
|
+
if (!client) {
|
|
624
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
625
|
+
}
|
|
626
|
+
if (!masterConfig) {
|
|
627
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
628
|
+
}
|
|
629
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
630
|
+
let createSubOrgParams = params?.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.passkeyAuth;
|
|
631
|
+
params = createSubOrgParams !== undefined ? {
|
|
632
|
+
...params,
|
|
633
|
+
createSubOrgParams
|
|
634
|
+
} : {
|
|
635
|
+
...params
|
|
636
|
+
};
|
|
637
|
+
const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
638
|
+
const websiteName = window.location.hostname;
|
|
639
|
+
const timestamp = new Date().toLocaleDateString() + "-" + new Date().toLocaleTimeString([], {
|
|
640
|
+
hour: "2-digit",
|
|
641
|
+
minute: "2-digit"
|
|
642
|
+
});
|
|
643
|
+
// We allow passkeyName to be passed in thru the provider or thru the params of this function directly.
|
|
644
|
+
// This is because signUpWithPasskey will create a new passkey using that name.
|
|
645
|
+
// Any extra authenticators will be created after the first one. (see core implementation)
|
|
646
|
+
const passkeyName = params?.passkeyDisplayName ?? masterConfig.auth?.createSuborgParams?.passkeyAuth?.passkeyName ?? `${websiteName}-${timestamp}`;
|
|
647
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithPasskey({
|
|
648
|
+
...params,
|
|
649
|
+
passkeyDisplayName: passkeyName,
|
|
650
|
+
expirationSeconds
|
|
651
|
+
}), callbacks, "Failed to sign up with passkey");
|
|
652
|
+
if (res) {
|
|
653
|
+
await handlePostAuth();
|
|
654
|
+
}
|
|
655
|
+
return res;
|
|
656
|
+
}
|
|
657
|
+
async function getWalletProviders(chain) {
|
|
658
|
+
if (!client) {
|
|
659
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
660
|
+
}
|
|
661
|
+
return await client.getWalletProviders(chain);
|
|
662
|
+
}
|
|
663
|
+
async function connectWalletAccount(walletProvider) {
|
|
664
|
+
if (!client) {
|
|
665
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
666
|
+
}
|
|
667
|
+
await client.connectWalletAccount(walletProvider);
|
|
668
|
+
await refreshWallets();
|
|
669
|
+
}
|
|
670
|
+
async function disconnectWalletAccount(walletProvider) {
|
|
671
|
+
if (!client) {
|
|
672
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
673
|
+
}
|
|
674
|
+
await client.disconnectWalletAccount(walletProvider);
|
|
675
|
+
// we only refresh the wallets if there is an active session
|
|
676
|
+
// this is needed because for WalletConnect you can unlink a wallet before
|
|
677
|
+
// actually being logged in
|
|
678
|
+
if (session) {
|
|
679
|
+
await refreshWallets();
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
async function switchWalletProviderChain(walletProvider, chainOrId) {
|
|
683
|
+
if (!client) {
|
|
684
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
685
|
+
}
|
|
686
|
+
await client.switchWalletProviderChain(walletProvider, chainOrId);
|
|
687
|
+
}
|
|
688
|
+
// TODO: MOE PLEASE COMMENT THESE
|
|
689
|
+
async function initializeProviders(getWalletProviders, onWalletsChanged) {
|
|
690
|
+
const cleanups = [];
|
|
691
|
+
const [ethProviders, solProviders] = await Promise.all([getWalletProviders(core.Chain.Ethereum), getWalletProviders(core.Chain.Solana)]);
|
|
692
|
+
function attachEthereumListeners(provider, onWalletsChanged) {
|
|
693
|
+
if (typeof provider.on !== "function") return;
|
|
694
|
+
const handleAccountsChanged = accounts => {
|
|
695
|
+
if (accounts.length === 0) onWalletsChanged();
|
|
696
|
+
};
|
|
697
|
+
const handleDisconnect = () => onWalletsChanged();
|
|
698
|
+
provider.on("accountsChanged", handleAccountsChanged);
|
|
699
|
+
provider.on("disconnect", handleDisconnect);
|
|
700
|
+
return () => {
|
|
701
|
+
provider.removeListener("accountsChanged", handleAccountsChanged);
|
|
702
|
+
provider.removeListener("disconnect", handleDisconnect);
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
function attachSolanaListeners(provider, onWalletsChanged) {
|
|
706
|
+
const cleanups = [];
|
|
707
|
+
const walletEvents = provider.features?.["standard:events"];
|
|
708
|
+
if (walletEvents?.on) {
|
|
709
|
+
const handleChange = event => {
|
|
710
|
+
if (event.type === "change" || event.type === "accountsChanged") {
|
|
711
|
+
onWalletsChanged();
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
walletEvents.on("change", handleChange);
|
|
715
|
+
walletEvents.on("accountsChanged", handleChange);
|
|
716
|
+
cleanups.push(() => {
|
|
717
|
+
walletEvents.off?.("change", handleChange);
|
|
718
|
+
walletEvents.off?.("accountsChanged", handleChange);
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
return cleanups.length > 0 ? () => {
|
|
722
|
+
cleanups.forEach(fn => fn());
|
|
723
|
+
} : () => {};
|
|
724
|
+
}
|
|
725
|
+
ethProviders.forEach(p => {
|
|
726
|
+
const cleanup = attachEthereumListeners(p.provider, onWalletsChanged);
|
|
727
|
+
if (cleanup) cleanups.push(cleanup);
|
|
728
|
+
});
|
|
729
|
+
solProviders.forEach(p => {
|
|
730
|
+
const cleanup = attachSolanaListeners(p.provider, onWalletsChanged);
|
|
731
|
+
if (cleanup) cleanups.push(cleanup);
|
|
732
|
+
});
|
|
733
|
+
return () => {
|
|
734
|
+
cleanups.forEach(remove => remove());
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
async function loginWithWallet(params) {
|
|
738
|
+
if (!client) {
|
|
739
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
740
|
+
}
|
|
741
|
+
const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
742
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.loginWithWallet({
|
|
743
|
+
...params,
|
|
744
|
+
expirationSeconds
|
|
745
|
+
}), callbacks, "Failed to login with wallet");
|
|
746
|
+
if (res) {
|
|
747
|
+
await handlePostAuth();
|
|
748
|
+
}
|
|
749
|
+
return res;
|
|
750
|
+
}
|
|
751
|
+
async function signUpWithWallet(params) {
|
|
752
|
+
if (!client) {
|
|
753
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
754
|
+
}
|
|
755
|
+
if (!masterConfig) {
|
|
756
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
757
|
+
}
|
|
758
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
759
|
+
let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.walletAuth;
|
|
760
|
+
params = createSubOrgParams !== undefined ? {
|
|
761
|
+
...params,
|
|
762
|
+
createSubOrgParams
|
|
763
|
+
} : {
|
|
764
|
+
...params
|
|
765
|
+
};
|
|
766
|
+
const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
767
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithWallet({
|
|
768
|
+
...params,
|
|
769
|
+
expirationSeconds
|
|
770
|
+
}), callbacks, "Failed to sign up with wallet");
|
|
771
|
+
if (res) {
|
|
772
|
+
await handlePostAuth();
|
|
773
|
+
}
|
|
774
|
+
return res;
|
|
775
|
+
}
|
|
776
|
+
async function loginOrSignupWithWallet(params) {
|
|
777
|
+
if (!client) {
|
|
778
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
779
|
+
}
|
|
780
|
+
if (!masterConfig) {
|
|
781
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
782
|
+
}
|
|
783
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
784
|
+
let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.walletAuth;
|
|
785
|
+
params = createSubOrgParams !== undefined ? {
|
|
786
|
+
...params,
|
|
787
|
+
createSubOrgParams
|
|
788
|
+
} : {
|
|
789
|
+
...params
|
|
790
|
+
};
|
|
791
|
+
const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
792
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.loginOrSignupWithWallet({
|
|
793
|
+
...params,
|
|
794
|
+
expirationSeconds
|
|
795
|
+
}), callbacks, "Failed to login or sign up with wallet");
|
|
796
|
+
if (res) {
|
|
797
|
+
await handlePostAuth();
|
|
798
|
+
}
|
|
799
|
+
return res;
|
|
800
|
+
}
|
|
801
|
+
async function initOtp(params) {
|
|
802
|
+
if (!client) {
|
|
803
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
804
|
+
}
|
|
805
|
+
return utils.withTurnkeyErrorHandling(() => client.initOtp(params), callbacks, "Failed to initialize OTP");
|
|
806
|
+
}
|
|
807
|
+
async function verifyOtp(params) {
|
|
808
|
+
if (!client) {
|
|
809
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
810
|
+
}
|
|
811
|
+
return utils.withTurnkeyErrorHandling(() => client.verifyOtp(params), callbacks, "Failed to verify OTP");
|
|
812
|
+
}
|
|
813
|
+
async function loginWithOtp(params) {
|
|
814
|
+
if (!client) {
|
|
815
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
816
|
+
}
|
|
817
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.loginWithOtp(params), callbacks, "Failed to login with OTP");
|
|
818
|
+
if (res) {
|
|
819
|
+
await handlePostAuth();
|
|
820
|
+
}
|
|
821
|
+
return res;
|
|
822
|
+
}
|
|
823
|
+
async function signUpWithOtp(params) {
|
|
824
|
+
if (!client) {
|
|
825
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
826
|
+
}
|
|
827
|
+
if (!masterConfig) {
|
|
828
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
829
|
+
}
|
|
830
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
831
|
+
let createSubOrgParams = params.createSubOrgParams;
|
|
832
|
+
if (!createSubOrgParams && masterConfig?.auth?.createSuborgParams) {
|
|
833
|
+
if (params.otpType === core.OtpType.Email) {
|
|
834
|
+
createSubOrgParams = masterConfig.auth.createSuborgParams.emailOtpAuth;
|
|
835
|
+
} else if (params.otpType === core.OtpType.Sms) {
|
|
836
|
+
createSubOrgParams = masterConfig.auth.createSuborgParams.smsOtpAuth;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
params = createSubOrgParams !== undefined ? {
|
|
840
|
+
...params,
|
|
841
|
+
createSubOrgParams
|
|
842
|
+
} : {
|
|
843
|
+
...params
|
|
844
|
+
};
|
|
845
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithOtp(params), callbacks, "Failed to sign up with OTP");
|
|
846
|
+
if (res) {
|
|
847
|
+
await handlePostAuth();
|
|
848
|
+
}
|
|
849
|
+
return res;
|
|
850
|
+
}
|
|
851
|
+
async function completeOtp(params) {
|
|
852
|
+
if (!client) {
|
|
853
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
854
|
+
}
|
|
855
|
+
if (!masterConfig) {
|
|
856
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
857
|
+
}
|
|
858
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
859
|
+
let createSubOrgParams = params.createSubOrgParams;
|
|
860
|
+
if (!createSubOrgParams && masterConfig?.auth?.createSuborgParams) {
|
|
861
|
+
if (params.otpType === core.OtpType.Email) {
|
|
862
|
+
createSubOrgParams = masterConfig.auth.createSuborgParams.emailOtpAuth;
|
|
863
|
+
} else if (params.otpType === core.OtpType.Sms) {
|
|
864
|
+
createSubOrgParams = masterConfig.auth.createSuborgParams.smsOtpAuth;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
params = createSubOrgParams !== undefined ? {
|
|
868
|
+
...params,
|
|
869
|
+
createSubOrgParams
|
|
870
|
+
} : {
|
|
871
|
+
...params
|
|
872
|
+
};
|
|
873
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.completeOtp(params), callbacks, "Failed to complete OTP");
|
|
874
|
+
if (res) {
|
|
875
|
+
await handlePostAuth();
|
|
876
|
+
}
|
|
877
|
+
return res;
|
|
878
|
+
}
|
|
879
|
+
async function completeOauth(params) {
|
|
880
|
+
if (!client) {
|
|
881
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
882
|
+
}
|
|
883
|
+
if (!masterConfig) {
|
|
884
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
885
|
+
}
|
|
886
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
887
|
+
const createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.oauth;
|
|
888
|
+
params = createSubOrgParams !== undefined ? {
|
|
889
|
+
...params,
|
|
890
|
+
createSubOrgParams
|
|
891
|
+
} : {
|
|
892
|
+
...params
|
|
893
|
+
};
|
|
894
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.completeOauth(params), callbacks, "Failed to complete OAuth");
|
|
895
|
+
if (res) {
|
|
896
|
+
await handlePostAuth();
|
|
897
|
+
}
|
|
898
|
+
return res;
|
|
899
|
+
}
|
|
900
|
+
async function loginWithOauth(params) {
|
|
901
|
+
if (!client) {
|
|
902
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
903
|
+
}
|
|
904
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.loginWithOauth(params), callbacks, "Failed to login with OAuth");
|
|
905
|
+
if (res) {
|
|
906
|
+
await handlePostAuth();
|
|
907
|
+
}
|
|
908
|
+
return res;
|
|
909
|
+
}
|
|
910
|
+
async function signUpWithOauth(params) {
|
|
911
|
+
if (!client) {
|
|
912
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
913
|
+
}
|
|
914
|
+
if (!masterConfig) {
|
|
915
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
916
|
+
}
|
|
917
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
918
|
+
let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.oauth;
|
|
919
|
+
params = createSubOrgParams !== undefined ? {
|
|
920
|
+
...params,
|
|
921
|
+
createSubOrgParams
|
|
922
|
+
} : {
|
|
923
|
+
...params
|
|
924
|
+
};
|
|
925
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithOauth(params), callbacks, "Failed to sign up with OAuth");
|
|
926
|
+
if (res) {
|
|
927
|
+
await handlePostAuth();
|
|
928
|
+
}
|
|
929
|
+
return res;
|
|
930
|
+
}
|
|
931
|
+
async function fetchWallets(params) {
|
|
932
|
+
if (!client) {
|
|
933
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
934
|
+
}
|
|
935
|
+
return utils.withTurnkeyErrorHandling(() => client.fetchWallets(params), callbacks, "Failed to fetch wallets");
|
|
936
|
+
}
|
|
937
|
+
async function fetchWalletAccounts(params) {
|
|
938
|
+
if (!client) {
|
|
939
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
940
|
+
}
|
|
941
|
+
return utils.withTurnkeyErrorHandling(() => client.fetchWalletAccounts(params), callbacks, "Failed to fetch wallet accounts");
|
|
942
|
+
}
|
|
943
|
+
async function signMessage(params) {
|
|
944
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
945
|
+
return utils.withTurnkeyErrorHandling(() => client.signMessage(params), callbacks, "Failed to sign message");
|
|
946
|
+
}
|
|
947
|
+
async function handleSignMessage(params) {
|
|
948
|
+
const {
|
|
949
|
+
successPageDuration = 2000
|
|
950
|
+
} = params;
|
|
951
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
952
|
+
return new Promise((resolve, reject) => {
|
|
953
|
+
pushPage({
|
|
954
|
+
key: "Sign Message",
|
|
955
|
+
content: jsxRuntime.jsx(Message.SignMessageModal, {
|
|
956
|
+
message: params.message,
|
|
957
|
+
subText: params?.subText,
|
|
958
|
+
walletAccount: params.walletAccount,
|
|
959
|
+
stampWith: params.stampWith,
|
|
960
|
+
successPageDuration: successPageDuration,
|
|
961
|
+
onSuccess: result => {
|
|
962
|
+
resolve(result);
|
|
963
|
+
},
|
|
964
|
+
onError: error => {
|
|
965
|
+
reject(error);
|
|
966
|
+
},
|
|
967
|
+
...(params?.encoding && {
|
|
968
|
+
encoding: params.encoding
|
|
969
|
+
}),
|
|
970
|
+
...(params?.hashFunction && {
|
|
971
|
+
hashFunction: params.hashFunction
|
|
972
|
+
}),
|
|
973
|
+
...(params?.addEthereumPrefix && {
|
|
974
|
+
addEthereumPrefix: params.addEthereumPrefix
|
|
975
|
+
})
|
|
976
|
+
})
|
|
977
|
+
});
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
async function signTransaction(params) {
|
|
981
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
982
|
+
return utils.withTurnkeyErrorHandling(() => client.signTransaction(params), callbacks, "Failed to sign transaction");
|
|
983
|
+
}
|
|
984
|
+
async function signAndSendTransaction(params) {
|
|
985
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
986
|
+
return utils.withTurnkeyErrorHandling(() => client.signAndSendTransaction(params), callbacks, "Failed to sign transaction");
|
|
987
|
+
}
|
|
988
|
+
async function fetchUser(params) {
|
|
989
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
990
|
+
return utils.withTurnkeyErrorHandling(() => client.fetchUser(params), callbacks, "Failed to fetch user");
|
|
991
|
+
}
|
|
992
|
+
async function updateUserEmail(params) {
|
|
993
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
994
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.updateUserEmail(params), callbacks, "Failed to update user email");
|
|
995
|
+
if (res) await refreshUser({
|
|
996
|
+
stampWith: params?.stampWith
|
|
997
|
+
});
|
|
998
|
+
return res;
|
|
999
|
+
}
|
|
1000
|
+
async function removeUserEmail(params) {
|
|
1001
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1002
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.removeUserEmail(params), callbacks, "Failed to remove user email");
|
|
1003
|
+
if (res) await refreshUser({
|
|
1004
|
+
stampWith: params?.stampWith
|
|
1005
|
+
});
|
|
1006
|
+
return res;
|
|
1007
|
+
}
|
|
1008
|
+
async function updateUserPhoneNumber(params) {
|
|
1009
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1010
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.updateUserPhoneNumber(params), callbacks, "Failed to update user phone number");
|
|
1011
|
+
if (res) await refreshUser({
|
|
1012
|
+
stampWith: params?.stampWith
|
|
1013
|
+
});
|
|
1014
|
+
return res;
|
|
1015
|
+
}
|
|
1016
|
+
async function removeUserPhoneNumber(params) {
|
|
1017
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1018
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.removeUserPhoneNumber(params), callbacks, "Failed to remove user phone number");
|
|
1019
|
+
if (res) await refreshUser({
|
|
1020
|
+
stampWith: params?.stampWith
|
|
1021
|
+
});
|
|
1022
|
+
return res;
|
|
1023
|
+
}
|
|
1024
|
+
async function updateUserName(params) {
|
|
1025
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1026
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.updateUserName(params), callbacks, "Failed to update user name");
|
|
1027
|
+
if (res) await refreshUser({
|
|
1028
|
+
stampWith: params?.stampWith
|
|
1029
|
+
});
|
|
1030
|
+
return res;
|
|
1031
|
+
}
|
|
1032
|
+
async function addOauthProvider(params) {
|
|
1033
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1034
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.addOauthProvider(params), callbacks, "Failed to add OAuth provider");
|
|
1035
|
+
if (res) await refreshUser({
|
|
1036
|
+
stampWith: params?.stampWith
|
|
1037
|
+
});
|
|
1038
|
+
return res;
|
|
1039
|
+
}
|
|
1040
|
+
async function removeOauthProviders(params) {
|
|
1041
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1042
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.removeOauthProviders(params), callbacks, "Failed to remove OAuth providers");
|
|
1043
|
+
if (res) await refreshUser({
|
|
1044
|
+
stampWith: params?.stampWith
|
|
1045
|
+
});
|
|
1046
|
+
return res;
|
|
1047
|
+
}
|
|
1048
|
+
async function addPasskey(params) {
|
|
1049
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1050
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.addPasskey(params), callbacks, "Failed to add passkey");
|
|
1051
|
+
if (res) await refreshUser({
|
|
1052
|
+
stampWith: params?.stampWith
|
|
1053
|
+
});
|
|
1054
|
+
return res;
|
|
1055
|
+
}
|
|
1056
|
+
async function removePasskeys(params) {
|
|
1057
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1058
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.removePasskeys(params), callbacks, "Failed to remove passkeys");
|
|
1059
|
+
if (res) await refreshUser({
|
|
1060
|
+
stampWith: params?.stampWith
|
|
1061
|
+
});
|
|
1062
|
+
return res;
|
|
1063
|
+
}
|
|
1064
|
+
async function createWallet(params) {
|
|
1065
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1066
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.createWallet(params), callbacks, "Failed to create wallet");
|
|
1067
|
+
if (res) await refreshWallets({
|
|
1068
|
+
stampWith: params?.stampWith
|
|
1069
|
+
});
|
|
1070
|
+
return res;
|
|
1071
|
+
}
|
|
1072
|
+
async function createWalletAccounts(params) {
|
|
1073
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1074
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.createWalletAccounts(params), callbacks, "Failed to create wallet accounts");
|
|
1075
|
+
if (res) await refreshWallets({
|
|
1076
|
+
stampWith: params?.stampWith
|
|
1077
|
+
});
|
|
1078
|
+
return res;
|
|
1079
|
+
}
|
|
1080
|
+
async function exportWallet(params) {
|
|
1081
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1082
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.exportWallet(params), callbacks, "Failed to export wallet");
|
|
1083
|
+
if (res) await refreshWallets({
|
|
1084
|
+
stampWith: params?.stampWith
|
|
1085
|
+
});
|
|
1086
|
+
return res;
|
|
1087
|
+
}
|
|
1088
|
+
async function importWallet(params) {
|
|
1089
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1090
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.importWallet(params), callbacks, "Failed to import wallet");
|
|
1091
|
+
if (res) await refreshWallets({
|
|
1092
|
+
stampWith: params?.stampWith
|
|
1093
|
+
});
|
|
1094
|
+
return res;
|
|
1095
|
+
}
|
|
1096
|
+
async function deleteSubOrganization(params) {
|
|
1097
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1098
|
+
return utils.withTurnkeyErrorHandling(() => client.deleteSubOrganization(params), callbacks, "Failed to delete sub-organization");
|
|
1099
|
+
}
|
|
1100
|
+
async function storeSession(params) {
|
|
1101
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1102
|
+
await utils.withTurnkeyErrorHandling(() => client.storeSession(params), callbacks, "Failed to store session");
|
|
1103
|
+
const sessionKey = await getActiveSessionKey();
|
|
1104
|
+
const session = await getSession({
|
|
1105
|
+
...(sessionKey && {
|
|
1106
|
+
sessionKey
|
|
1107
|
+
})
|
|
1108
|
+
});
|
|
1109
|
+
if (session && sessionKey) await scheduleSessionExpiration({
|
|
1110
|
+
sessionKey,
|
|
1111
|
+
expiry: session.expiry
|
|
1112
|
+
});
|
|
1113
|
+
const allSessions = await getAllSessions();
|
|
1114
|
+
setSession(session);
|
|
1115
|
+
setAllSessions(allSessions);
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
async function clearSession(params) {
|
|
1119
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1120
|
+
await utils.withTurnkeyErrorHandling(() => client.clearSession(params), callbacks, "Failed to clear session");
|
|
1121
|
+
const session = await getSession();
|
|
1122
|
+
const allSessions = await getAllSessions();
|
|
1123
|
+
setSession(session);
|
|
1124
|
+
setAllSessions(allSessions);
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
async function clearAllSessions() {
|
|
1128
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1129
|
+
setSession(undefined);
|
|
1130
|
+
setAllSessions(undefined);
|
|
1131
|
+
return await utils.withTurnkeyErrorHandling(() => client.clearAllSessions(), callbacks, "Failed to clear all sessions");
|
|
1132
|
+
}
|
|
1133
|
+
async function refreshSession(params) {
|
|
1134
|
+
if (!client) {
|
|
1135
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1136
|
+
}
|
|
1137
|
+
const activeSessionKey = await client.getActiveSessionKey();
|
|
1138
|
+
if (!activeSessionKey) {
|
|
1139
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
1140
|
+
}
|
|
1141
|
+
const sessionKey = params?.sessionKey ?? activeSessionKey;
|
|
1142
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.refreshSession({
|
|
1143
|
+
...params
|
|
1144
|
+
}), callbacks, "Failed to refresh session");
|
|
1145
|
+
const session = await getSession({
|
|
1146
|
+
sessionKey
|
|
1147
|
+
});
|
|
1148
|
+
if (session && sessionKey) {
|
|
1149
|
+
await scheduleSessionExpiration({
|
|
1150
|
+
sessionKey,
|
|
1151
|
+
expiry: session.expiry,
|
|
1152
|
+
...(params?.expirationSeconds && {
|
|
1153
|
+
expirationSeconds: params?.expirationSeconds
|
|
1154
|
+
})
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
const allSessions = await getAllSessions();
|
|
1158
|
+
setSession(session);
|
|
1159
|
+
setAllSessions(allSessions);
|
|
1160
|
+
return res;
|
|
1161
|
+
}
|
|
1162
|
+
async function getSession(params) {
|
|
1163
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1164
|
+
return utils.withTurnkeyErrorHandling(() => client.getSession(params), callbacks, "Failed to get session");
|
|
1165
|
+
}
|
|
1166
|
+
async function getAllSessions() {
|
|
1167
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1168
|
+
return utils.withTurnkeyErrorHandling(() => client.getAllSessions(), callbacks, "Failed to get all sessions");
|
|
1169
|
+
}
|
|
1170
|
+
async function setActiveSession(params) {
|
|
1171
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1172
|
+
const session = await utils.withTurnkeyErrorHandling(() => client.getSession({
|
|
1173
|
+
sessionKey: params.sessionKey
|
|
1174
|
+
}), callbacks, "Failed to get session");
|
|
1175
|
+
if (!session) {
|
|
1176
|
+
throw new sdkTypes.TurnkeyError("Session not found.", sdkTypes.TurnkeyErrorCodes.NOT_FOUND);
|
|
1177
|
+
}
|
|
1178
|
+
await utils.withTurnkeyErrorHandling(() => client.setActiveSession(params), callbacks, "Failed to set active session");
|
|
1179
|
+
setSession(session);
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
async function getActiveSessionKey() {
|
|
1183
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1184
|
+
return utils.withTurnkeyErrorHandling(() => client.getActiveSessionKey(), callbacks, "Failed to get active session key");
|
|
1185
|
+
}
|
|
1186
|
+
async function clearUnusedKeyPairs() {
|
|
1187
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1188
|
+
return utils.withTurnkeyErrorHandling(() => client.clearUnusedKeyPairs(), callbacks, "Failed to clear unused key pairs");
|
|
1189
|
+
}
|
|
1190
|
+
async function createApiKeyPair(params) {
|
|
1191
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1192
|
+
return utils.withTurnkeyErrorHandling(() => client.createApiKeyPair(params), callbacks, "Failed to create API key pair");
|
|
1193
|
+
}
|
|
1194
|
+
async function getProxyAuthConfig() {
|
|
1195
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1196
|
+
return utils.withTurnkeyErrorHandling(() => client.getProxyAuthConfig(), callbacks, "Failed to get proxy auth config");
|
|
1197
|
+
}
|
|
1198
|
+
async function refreshUser(params) {
|
|
1199
|
+
const {
|
|
1200
|
+
stampWith
|
|
1201
|
+
} = params || {};
|
|
1202
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1203
|
+
const user = await utils.withTurnkeyErrorHandling(() => fetchUser({
|
|
1204
|
+
stampWith
|
|
1205
|
+
}), callbacks, "Failed to refresh user");
|
|
1206
|
+
if (user) {
|
|
1207
|
+
setUser(user);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
async function refreshWallets(params) {
|
|
1211
|
+
const {
|
|
1212
|
+
stampWith
|
|
1213
|
+
} = params || {};
|
|
1214
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1215
|
+
const wallets = await utils.withTurnkeyErrorHandling(() => fetchWallets({
|
|
1216
|
+
stampWith
|
|
1217
|
+
}), callbacks, "Failed to refresh wallets");
|
|
1218
|
+
if (wallets) {
|
|
1219
|
+
setWallets(wallets);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
async function handleGoogleOauth(params) {
|
|
1223
|
+
const {
|
|
1224
|
+
clientId = masterConfig?.auth?.oauthConfig?.googleClientId,
|
|
1225
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1226
|
+
additionalState: additionalParameters
|
|
1227
|
+
} = params || {};
|
|
1228
|
+
try {
|
|
1229
|
+
if (!masterConfig) {
|
|
1230
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1231
|
+
}
|
|
1232
|
+
if (!clientId) {
|
|
1233
|
+
throw new sdkTypes.TurnkeyError("Google Client ID is not configured.", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1234
|
+
}
|
|
1235
|
+
if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
|
|
1236
|
+
throw new sdkTypes.TurnkeyError("OAuth Redirect URI is not configured.", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1237
|
+
}
|
|
1238
|
+
const flow = openInPage ? "redirect" : "popup";
|
|
1239
|
+
const redirectURI = masterConfig.auth?.oauthConfig.oauthRedirectUri.replace(/\/$/, "");
|
|
1240
|
+
// Create key pair and generate nonce
|
|
1241
|
+
const publicKey = await createApiKeyPair();
|
|
1242
|
+
if (!publicKey) {
|
|
1243
|
+
throw new Error("Failed to create public key for OAuth.");
|
|
1244
|
+
}
|
|
1245
|
+
const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
|
|
1246
|
+
// Construct Google Auth URL
|
|
1247
|
+
const googleAuthUrl = new URL(utils.GOOGLE_AUTH_URL);
|
|
1248
|
+
googleAuthUrl.searchParams.set("client_id", clientId);
|
|
1249
|
+
googleAuthUrl.searchParams.set("redirect_uri", redirectURI);
|
|
1250
|
+
googleAuthUrl.searchParams.set("response_type", "id_token");
|
|
1251
|
+
googleAuthUrl.searchParams.set("scope", "openid email profile");
|
|
1252
|
+
googleAuthUrl.searchParams.set("nonce", nonce);
|
|
1253
|
+
googleAuthUrl.searchParams.set("prompt", "select_account");
|
|
1254
|
+
// Create state parameter
|
|
1255
|
+
let state = `provider=google&flow=${flow}&publicKey=${encodeURIComponent(publicKey)}`;
|
|
1256
|
+
if (additionalParameters) {
|
|
1257
|
+
const additionalState = Object.entries(additionalParameters).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
|
|
1258
|
+
if (additionalState) {
|
|
1259
|
+
state += `&${additionalState}`;
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
googleAuthUrl.searchParams.set("state", state);
|
|
1263
|
+
if (openInPage) {
|
|
1264
|
+
// Redirect current page to Google Auth
|
|
1265
|
+
window.location.href = googleAuthUrl.toString();
|
|
1266
|
+
return new Promise((_, reject) => {
|
|
1267
|
+
// By here, the page should have already redirected. We wait here since the function is async.
|
|
1268
|
+
// We want any function that runs this to simply wait until the page redirects.
|
|
1269
|
+
// A 5 min timeout is set just in case, idk
|
|
1270
|
+
const timeout = setTimeout(() => {
|
|
1271
|
+
reject(new Error("Authentication timed out."));
|
|
1272
|
+
}, 300000); // 5 minutes
|
|
1273
|
+
// If the page is unloaded (user navigates away), clear the timeout
|
|
1274
|
+
window.addEventListener("beforeunload", () => clearTimeout(timeout));
|
|
1275
|
+
});
|
|
1276
|
+
} else {
|
|
1277
|
+
// Open popup window
|
|
1278
|
+
const width = utils.popupWidth;
|
|
1279
|
+
const height = utils.popupHeight;
|
|
1280
|
+
const left = window.screenX + (window.innerWidth - width) / 2;
|
|
1281
|
+
const top = window.screenY + (window.innerHeight - height) / 2;
|
|
1282
|
+
const authWindow = window.open("about:blank", "_blank", `width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`);
|
|
1283
|
+
if (!authWindow) {
|
|
1284
|
+
throw new Error("Failed to open Google login window.");
|
|
1285
|
+
}
|
|
1286
|
+
authWindow.location.href = googleAuthUrl.toString();
|
|
1287
|
+
// Return a promise that resolves when the OAuth flow completes
|
|
1288
|
+
// This following code will only run for the popup flow
|
|
1289
|
+
return new Promise((resolve, reject) => {
|
|
1290
|
+
const interval = setInterval(() => {
|
|
1291
|
+
try {
|
|
1292
|
+
// Check if window was closed without completing auth
|
|
1293
|
+
if (authWindow.closed) {
|
|
1294
|
+
clearInterval(interval);
|
|
1295
|
+
reject(new Error("Authentication window was closed."));
|
|
1296
|
+
return;
|
|
1297
|
+
}
|
|
1298
|
+
const url = authWindow.location.href || "";
|
|
1299
|
+
if (url.startsWith(window.location.origin)) {
|
|
1300
|
+
const hashParams = new URLSearchParams(url.split("#")[1]);
|
|
1301
|
+
const idToken = hashParams.get("id_token");
|
|
1302
|
+
if (idToken) {
|
|
1303
|
+
authWindow.close();
|
|
1304
|
+
clearInterval(interval);
|
|
1305
|
+
if (params?.onOauthSuccess) {
|
|
1306
|
+
params.onOauthSuccess({
|
|
1307
|
+
oidcToken: idToken,
|
|
1308
|
+
providerName: "google"
|
|
1309
|
+
});
|
|
1310
|
+
} else if (callbacks?.onOauthRedirect) {
|
|
1311
|
+
callbacks.onOauthRedirect({
|
|
1312
|
+
idToken,
|
|
1313
|
+
publicKey
|
|
1314
|
+
});
|
|
1315
|
+
} else {
|
|
1316
|
+
completeOauth({
|
|
1317
|
+
oidcToken: idToken,
|
|
1318
|
+
publicKey,
|
|
1319
|
+
providerName: "google"
|
|
1320
|
+
}).then(() => resolve()).catch(reject);
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
resolve();
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
} catch (error) {
|
|
1327
|
+
// Ignore cross-origin errors
|
|
1328
|
+
}
|
|
1329
|
+
}, 500);
|
|
1330
|
+
if (authWindow.closed) {
|
|
1331
|
+
clearInterval(interval);
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
} catch (error) {
|
|
1336
|
+
throw error;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
async function handleAppleOauth(params) {
|
|
1340
|
+
const {
|
|
1341
|
+
clientId = masterConfig?.auth?.oauthConfig?.appleClientId,
|
|
1342
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1343
|
+
additionalState: additionalParameters
|
|
1344
|
+
} = params || {};
|
|
1345
|
+
try {
|
|
1346
|
+
if (!masterConfig) {
|
|
1347
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1348
|
+
}
|
|
1349
|
+
if (!clientId) {
|
|
1350
|
+
throw new sdkTypes.TurnkeyError("Apple Client ID is not configured.", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1351
|
+
}
|
|
1352
|
+
if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
|
|
1353
|
+
throw new sdkTypes.TurnkeyError("OAuth Redirect URI is not configured.", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1354
|
+
}
|
|
1355
|
+
const flow = openInPage ? "redirect" : "popup";
|
|
1356
|
+
const redirectURI = masterConfig.auth?.oauthConfig.oauthRedirectUri; // TODO (Amir): Apple needs the '/' at the end. Maybe we should add it if not there?
|
|
1357
|
+
// Create key pair and generate nonce
|
|
1358
|
+
const publicKey = await createApiKeyPair();
|
|
1359
|
+
if (!publicKey) {
|
|
1360
|
+
throw new Error("Failed to create public key for OAuth.");
|
|
1361
|
+
}
|
|
1362
|
+
const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
|
|
1363
|
+
// Construct Apple Auth URL
|
|
1364
|
+
const appleAuthUrl = new URL(utils.APPLE_AUTH_URL);
|
|
1365
|
+
appleAuthUrl.searchParams.set("client_id", clientId);
|
|
1366
|
+
appleAuthUrl.searchParams.set("redirect_uri", redirectURI);
|
|
1367
|
+
appleAuthUrl.searchParams.set("response_type", "code id_token");
|
|
1368
|
+
appleAuthUrl.searchParams.set("response_mode", "fragment");
|
|
1369
|
+
appleAuthUrl.searchParams.set("nonce", nonce);
|
|
1370
|
+
// Create state parameter
|
|
1371
|
+
let state = `provider=apple&flow=${flow}&publicKey=${encodeURIComponent(publicKey)}`;
|
|
1372
|
+
if (additionalParameters) {
|
|
1373
|
+
const additionalState = Object.entries(additionalParameters).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
|
|
1374
|
+
if (additionalState) {
|
|
1375
|
+
state += `&${additionalState}`;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
appleAuthUrl.searchParams.set("state", state);
|
|
1379
|
+
if (openInPage) {
|
|
1380
|
+
// Redirect current page to Apple Auth
|
|
1381
|
+
window.location.href = appleAuthUrl.toString();
|
|
1382
|
+
return new Promise((_, reject) => {
|
|
1383
|
+
// Set a timeout just in case the redirect doesn't happen
|
|
1384
|
+
const timeout = setTimeout(() => {
|
|
1385
|
+
reject(new Error("Authentication timed out."));
|
|
1386
|
+
}, 300000); // 5 minutes
|
|
1387
|
+
// If the page is unloaded (user navigates away), clear the timeout
|
|
1388
|
+
window.addEventListener("beforeunload", () => clearTimeout(timeout));
|
|
1389
|
+
});
|
|
1390
|
+
} else {
|
|
1391
|
+
// Open popup window
|
|
1392
|
+
const width = utils.popupWidth;
|
|
1393
|
+
const height = utils.popupHeight;
|
|
1394
|
+
const left = window.screenX + (window.innerWidth - width) / 2;
|
|
1395
|
+
const top = window.screenY + (window.innerHeight - height) / 2;
|
|
1396
|
+
const authWindow = window.open("about:blank", "_blank", `width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`);
|
|
1397
|
+
if (!authWindow) {
|
|
1398
|
+
throw new Error("Failed to open Apple login window.");
|
|
1399
|
+
}
|
|
1400
|
+
authWindow.location.href = appleAuthUrl.toString();
|
|
1401
|
+
// Return a promise that resolves when the OAuth flow completes
|
|
1402
|
+
return new Promise((resolve, reject) => {
|
|
1403
|
+
const interval = setInterval(() => {
|
|
1404
|
+
try {
|
|
1405
|
+
// Check if window was closed without completing auth
|
|
1406
|
+
if (authWindow.closed) {
|
|
1407
|
+
clearInterval(interval);
|
|
1408
|
+
reject(new Error("Authentication window was closed."));
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
const url = authWindow.location.href || "";
|
|
1412
|
+
if (url.startsWith(window.location.origin)) {
|
|
1413
|
+
const hashParams = new URLSearchParams(url.split("#")[1]);
|
|
1414
|
+
const idToken = hashParams.get("id_token");
|
|
1415
|
+
if (idToken) {
|
|
1416
|
+
authWindow.close();
|
|
1417
|
+
clearInterval(interval);
|
|
1418
|
+
if (params?.onOauthSuccess) {
|
|
1419
|
+
params.onOauthSuccess({
|
|
1420
|
+
oidcToken: idToken,
|
|
1421
|
+
providerName: "apple"
|
|
1422
|
+
});
|
|
1423
|
+
} else if (callbacks?.onOauthRedirect) {
|
|
1424
|
+
callbacks.onOauthRedirect({
|
|
1425
|
+
idToken,
|
|
1426
|
+
publicKey
|
|
1427
|
+
});
|
|
1428
|
+
} else {
|
|
1429
|
+
completeOauth({
|
|
1430
|
+
oidcToken: idToken,
|
|
1431
|
+
publicKey,
|
|
1432
|
+
providerName: "apple"
|
|
1433
|
+
}).then(() => resolve()).catch(reject);
|
|
1434
|
+
return;
|
|
1435
|
+
}
|
|
1436
|
+
resolve();
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
} catch (error) {
|
|
1440
|
+
// Ignore cross-origin errors
|
|
1441
|
+
}
|
|
1442
|
+
}, 500);
|
|
1443
|
+
if (authWindow.closed) {
|
|
1444
|
+
clearInterval(interval);
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
} catch (error) {
|
|
1449
|
+
throw error;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
async function handleFacebookOauth(params) {
|
|
1453
|
+
const {
|
|
1454
|
+
clientId = masterConfig?.auth?.oauthConfig?.facebookClientId,
|
|
1455
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1456
|
+
additionalState: additionalParameters
|
|
1457
|
+
} = params || {};
|
|
1458
|
+
try {
|
|
1459
|
+
if (!masterConfig) {
|
|
1460
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1461
|
+
}
|
|
1462
|
+
if (!clientId) {
|
|
1463
|
+
throw new sdkTypes.TurnkeyError("Facebook Client ID is not configured.", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1464
|
+
}
|
|
1465
|
+
if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
|
|
1466
|
+
throw new sdkTypes.TurnkeyError("OAuth Redirect URI is not configured.", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
1467
|
+
}
|
|
1468
|
+
const flow = openInPage ? "redirect" : "popup";
|
|
1469
|
+
const redirectURI = masterConfig.auth?.oauthConfig.oauthRedirectUri;
|
|
1470
|
+
// Create key pair and generate nonce
|
|
1471
|
+
const publicKey = await createApiKeyPair();
|
|
1472
|
+
if (!publicKey) {
|
|
1473
|
+
throw new Error("Failed to create public key for OAuth.");
|
|
1474
|
+
}
|
|
1475
|
+
const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
|
|
1476
|
+
// Generate PKCE challenge pair
|
|
1477
|
+
const {
|
|
1478
|
+
verifier,
|
|
1479
|
+
codeChallenge
|
|
1480
|
+
} = await utils.generateChallengePair();
|
|
1481
|
+
// Store verifier for later token exchange
|
|
1482
|
+
sessionStorage.setItem("facebook_verifier", verifier);
|
|
1483
|
+
// Construct Facebook Auth URL
|
|
1484
|
+
const facebookAuthUrl = new URL(utils.FACEBOOK_AUTH_URL);
|
|
1485
|
+
facebookAuthUrl.searchParams.set("client_id", clientId);
|
|
1486
|
+
facebookAuthUrl.searchParams.set("redirect_uri", redirectURI);
|
|
1487
|
+
facebookAuthUrl.searchParams.set("response_type", "code");
|
|
1488
|
+
facebookAuthUrl.searchParams.set("code_challenge", codeChallenge);
|
|
1489
|
+
facebookAuthUrl.searchParams.set("code_challenge_method", "S256");
|
|
1490
|
+
facebookAuthUrl.searchParams.set("nonce", nonce);
|
|
1491
|
+
facebookAuthUrl.searchParams.set("scope", "openid");
|
|
1492
|
+
// Create state parameter
|
|
1493
|
+
let state = `provider=facebook&flow=${flow}&publicKey=${encodeURIComponent(publicKey)}`;
|
|
1494
|
+
if (additionalParameters) {
|
|
1495
|
+
const additionalState = Object.entries(additionalParameters).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
|
|
1496
|
+
if (additionalState) {
|
|
1497
|
+
state += `&${additionalState}`;
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
facebookAuthUrl.searchParams.set("state", state);
|
|
1501
|
+
if (openInPage) {
|
|
1502
|
+
// Redirect current page to Facebook Auth
|
|
1503
|
+
window.location.href = facebookAuthUrl.toString();
|
|
1504
|
+
return new Promise((_, reject) => {
|
|
1505
|
+
// Set a timeout just in case the redirect doesn't happen
|
|
1506
|
+
const timeout = setTimeout(() => {
|
|
1507
|
+
reject(new Error("Authentication timed out."));
|
|
1508
|
+
}, 300000); // 5 minutes
|
|
1509
|
+
// If the page is unloaded (user navigates away), clear the timeout
|
|
1510
|
+
window.addEventListener("beforeunload", () => clearTimeout(timeout));
|
|
1511
|
+
});
|
|
1512
|
+
} else {
|
|
1513
|
+
// Open popup window
|
|
1514
|
+
const width = utils.popupWidth;
|
|
1515
|
+
const height = utils.popupHeight;
|
|
1516
|
+
const left = window.screenX + (window.innerWidth - width) / 2;
|
|
1517
|
+
const top = window.screenY + (window.innerHeight - height) / 2;
|
|
1518
|
+
const authWindow = window.open("about:blank", "_blank", `width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`);
|
|
1519
|
+
if (!authWindow) {
|
|
1520
|
+
throw new Error("Failed to open Facebook login window.");
|
|
1521
|
+
}
|
|
1522
|
+
authWindow.location.href = facebookAuthUrl.toString();
|
|
1523
|
+
// Return a promise that resolves when the OAuth flow completes
|
|
1524
|
+
return new Promise((resolve, reject) => {
|
|
1525
|
+
const interval = setInterval(() => {
|
|
1526
|
+
try {
|
|
1527
|
+
// Check if window was closed without completing auth
|
|
1528
|
+
if (authWindow.closed) {
|
|
1529
|
+
clearInterval(interval);
|
|
1530
|
+
reject(new Error("Authentication window was closed."));
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
const url = authWindow.location.href || "";
|
|
1534
|
+
if (url.startsWith(window.location.origin)) {
|
|
1535
|
+
const urlParams = new URLSearchParams(new URL(url).search);
|
|
1536
|
+
const authCode = urlParams.get("code");
|
|
1537
|
+
const stateParam = urlParams.get("state");
|
|
1538
|
+
if (authCode && stateParam && stateParam.includes("provider=facebook")) {
|
|
1539
|
+
authWindow.close();
|
|
1540
|
+
clearInterval(interval);
|
|
1541
|
+
// Exchange code for token
|
|
1542
|
+
const verifier = sessionStorage.getItem("facebook_verifier");
|
|
1543
|
+
if (!verifier) {
|
|
1544
|
+
reject(new Error("Missing PKCE verifier"));
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
utils.exchangeCodeForToken(clientId, redirectURI, authCode, verifier).then(tokenData => {
|
|
1548
|
+
sessionStorage.removeItem("facebook_verifier");
|
|
1549
|
+
if (params?.onOauthSuccess) {
|
|
1550
|
+
params.onOauthSuccess({
|
|
1551
|
+
oidcToken: tokenData.id_token,
|
|
1552
|
+
providerName: "apple"
|
|
1553
|
+
});
|
|
1554
|
+
} else if (callbacks?.onOauthRedirect) {
|
|
1555
|
+
callbacks.onOauthRedirect({
|
|
1556
|
+
idToken: tokenData.id_token,
|
|
1557
|
+
publicKey
|
|
1558
|
+
});
|
|
1559
|
+
} else {
|
|
1560
|
+
completeOauth({
|
|
1561
|
+
oidcToken: tokenData.id_token,
|
|
1562
|
+
publicKey,
|
|
1563
|
+
providerName: "facebook"
|
|
1564
|
+
}).then(() => resolve()).catch(reject);
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1567
|
+
resolve();
|
|
1568
|
+
}).catch(reject);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
} catch (error) {
|
|
1572
|
+
// Ignore cross-origin errors
|
|
1573
|
+
}
|
|
1574
|
+
}, 500);
|
|
1575
|
+
if (authWindow.closed) {
|
|
1576
|
+
clearInterval(interval);
|
|
1577
|
+
}
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
} catch (error) {
|
|
1581
|
+
throw error;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
const handleLogin = async () => {
|
|
1585
|
+
pushPage({
|
|
1586
|
+
key: "Log in or sign up",
|
|
1587
|
+
content: jsxRuntime.jsx(index.AuthComponent, {})
|
|
1588
|
+
});
|
|
1589
|
+
};
|
|
1590
|
+
const handleExport = async params => {
|
|
1591
|
+
const {
|
|
1592
|
+
walletId,
|
|
1593
|
+
exportType,
|
|
1594
|
+
targetPublicKey,
|
|
1595
|
+
stampWith
|
|
1596
|
+
} = params;
|
|
1597
|
+
pushPage({
|
|
1598
|
+
key: "Export Wallet",
|
|
1599
|
+
content: jsxRuntime.jsx(Export.ExportComponent, {
|
|
1600
|
+
walletId: walletId ?? wallets[0]?.walletId,
|
|
1601
|
+
exportType: exportType ?? base.ExportType.Wallet,
|
|
1602
|
+
...(targetPublicKey !== undefined ? {
|
|
1603
|
+
targetPublicKey
|
|
1604
|
+
} : {}),
|
|
1605
|
+
...(stampWith !== undefined ? {
|
|
1606
|
+
stampWith
|
|
1607
|
+
} : {})
|
|
1608
|
+
})
|
|
1609
|
+
});
|
|
1610
|
+
};
|
|
1611
|
+
const handleImport = async params => {
|
|
1612
|
+
const {
|
|
1613
|
+
defaultWalletAccounts,
|
|
1614
|
+
successPageDuration = 2000,
|
|
1615
|
+
stampWith
|
|
1616
|
+
} = params || {};
|
|
1617
|
+
try {
|
|
1618
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => pushPage({
|
|
1619
|
+
key: "Import Wallet",
|
|
1620
|
+
content: jsxRuntime.jsx(Import.ImportComponent, {
|
|
1621
|
+
onError: error => {
|
|
1622
|
+
reject(error);
|
|
1623
|
+
},
|
|
1624
|
+
onSuccess: walletId => resolve(walletId),
|
|
1625
|
+
...(defaultWalletAccounts !== undefined && {
|
|
1626
|
+
defaultWalletAccounts
|
|
1627
|
+
}),
|
|
1628
|
+
...(successPageDuration !== undefined && {
|
|
1629
|
+
successPageDuration
|
|
1630
|
+
}),
|
|
1631
|
+
...(stampWith !== undefined && {
|
|
1632
|
+
stampWith
|
|
1633
|
+
})
|
|
1634
|
+
})
|
|
1635
|
+
})));
|
|
1636
|
+
} catch (error) {
|
|
1637
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
1638
|
+
throw error;
|
|
1639
|
+
}
|
|
1640
|
+
throw new sdkTypes.TurnkeyError("Failed to import wallet.", sdkTypes.TurnkeyErrorCodes.IMPORT_WALLET_ERROR, error);
|
|
1641
|
+
}
|
|
1642
|
+
};
|
|
1643
|
+
const handleUpdateUserName = async params => {
|
|
1644
|
+
const {
|
|
1645
|
+
successPageDuration = 2000,
|
|
1646
|
+
subTitle,
|
|
1647
|
+
title,
|
|
1648
|
+
stampWith
|
|
1649
|
+
} = params || {};
|
|
1650
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1651
|
+
if (!session) {
|
|
1652
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
1653
|
+
}
|
|
1654
|
+
const onSuccess = () => {
|
|
1655
|
+
if (!successPageDuration) return;
|
|
1656
|
+
pushPage({
|
|
1657
|
+
key: "success",
|
|
1658
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
1659
|
+
text: "User name changed successfully!",
|
|
1660
|
+
duration: successPageDuration,
|
|
1661
|
+
onComplete: () => {
|
|
1662
|
+
closeModal();
|
|
1663
|
+
}
|
|
1664
|
+
}),
|
|
1665
|
+
preventBack: true,
|
|
1666
|
+
showTitle: false
|
|
1667
|
+
});
|
|
1668
|
+
};
|
|
1669
|
+
try {
|
|
1670
|
+
if (!params?.userName && params?.userName !== "") {
|
|
1671
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
1672
|
+
pushPage({
|
|
1673
|
+
key: "Update User Name",
|
|
1674
|
+
content: jsxRuntime.jsx(UpdateUserName.UpdateUserName, {
|
|
1675
|
+
onSuccess: userId => {
|
|
1676
|
+
resolve(userId);
|
|
1677
|
+
},
|
|
1678
|
+
onError: error => {
|
|
1679
|
+
reject(error);
|
|
1680
|
+
},
|
|
1681
|
+
successPageDuration: successPageDuration,
|
|
1682
|
+
stampWith: stampWith,
|
|
1683
|
+
...(title !== undefined ? {
|
|
1684
|
+
title
|
|
1685
|
+
} : {}),
|
|
1686
|
+
...(subTitle !== undefined ? {
|
|
1687
|
+
subTitle
|
|
1688
|
+
} : {})
|
|
1689
|
+
}),
|
|
1690
|
+
showTitle: false
|
|
1691
|
+
});
|
|
1692
|
+
}));
|
|
1693
|
+
} else {
|
|
1694
|
+
const res = await updateUserName({
|
|
1695
|
+
userName: params.userName,
|
|
1696
|
+
userId: user.userId,
|
|
1697
|
+
stampWith
|
|
1698
|
+
});
|
|
1699
|
+
onSuccess();
|
|
1700
|
+
return res;
|
|
1701
|
+
}
|
|
1702
|
+
} catch (error) {
|
|
1703
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
1704
|
+
throw error;
|
|
1705
|
+
}
|
|
1706
|
+
throw new sdkTypes.TurnkeyError("Failed to update user name.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_NAME_ERROR, error);
|
|
1707
|
+
}
|
|
1708
|
+
};
|
|
1709
|
+
const handleUpdateUserPhoneNumber = async params => {
|
|
1710
|
+
const {
|
|
1711
|
+
successPageDuration = 2000,
|
|
1712
|
+
subTitle,
|
|
1713
|
+
title
|
|
1714
|
+
} = params || {};
|
|
1715
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1716
|
+
if (!session) {
|
|
1717
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
1718
|
+
}
|
|
1719
|
+
if (!masterConfig) {
|
|
1720
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.CONFIG_NOT_INITIALIZED);
|
|
1721
|
+
}
|
|
1722
|
+
if (!masterConfig.auth?.methods?.smsOtpAuthEnabled) {
|
|
1723
|
+
throw new sdkTypes.TurnkeyError("SMS OTP authentication is not enabled in the configuration.", sdkTypes.TurnkeyErrorCodes.AUTH_METHOD_NOT_ENABLED);
|
|
1724
|
+
}
|
|
1725
|
+
const onSuccess = () => {
|
|
1726
|
+
if (!successPageDuration) return;
|
|
1727
|
+
pushPage({
|
|
1728
|
+
key: "success",
|
|
1729
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
1730
|
+
text: "Phone number changed successfully!",
|
|
1731
|
+
duration: successPageDuration,
|
|
1732
|
+
onComplete: () => {
|
|
1733
|
+
closeModal();
|
|
1734
|
+
}
|
|
1735
|
+
}),
|
|
1736
|
+
preventBack: true,
|
|
1737
|
+
showTitle: false
|
|
1738
|
+
});
|
|
1739
|
+
};
|
|
1740
|
+
try {
|
|
1741
|
+
if (!params?.phoneNumber && params?.phoneNumber !== "") {
|
|
1742
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
1743
|
+
pushPage({
|
|
1744
|
+
key: "Update Phone Number",
|
|
1745
|
+
content: jsxRuntime.jsx(UpdatePhoneNumber.UpdatePhoneNumber, {
|
|
1746
|
+
successPageDuration: successPageDuration,
|
|
1747
|
+
onSuccess: userId => resolve(userId),
|
|
1748
|
+
onError: error => reject(error),
|
|
1749
|
+
...(title !== undefined ? {
|
|
1750
|
+
title
|
|
1751
|
+
} : {}),
|
|
1752
|
+
...(subTitle !== undefined ? {
|
|
1753
|
+
subTitle
|
|
1754
|
+
} : {})
|
|
1755
|
+
}),
|
|
1756
|
+
showTitle: false
|
|
1757
|
+
});
|
|
1758
|
+
}));
|
|
1759
|
+
} else {
|
|
1760
|
+
const otpId = await initOtp({
|
|
1761
|
+
otpType: core.OtpType.Sms,
|
|
1762
|
+
contact: params.phoneNumber
|
|
1763
|
+
});
|
|
1764
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
1765
|
+
pushPage({
|
|
1766
|
+
key: "Update Phone Number",
|
|
1767
|
+
content: jsxRuntime.jsx(OTP.OtpVerification, {
|
|
1768
|
+
otpType: core.OtpType.Sms,
|
|
1769
|
+
contact: params.phoneNumber,
|
|
1770
|
+
otpId: otpId,
|
|
1771
|
+
onContinue: async otpCode => {
|
|
1772
|
+
try {
|
|
1773
|
+
const {
|
|
1774
|
+
verificationToken
|
|
1775
|
+
} = await verifyOtp({
|
|
1776
|
+
otpId,
|
|
1777
|
+
otpCode,
|
|
1778
|
+
contact: params.phoneNumber,
|
|
1779
|
+
otpType: core.OtpType.Sms
|
|
1780
|
+
});
|
|
1781
|
+
const res = await updateUserPhoneNumber({
|
|
1782
|
+
phoneNumber: params.phoneNumber,
|
|
1783
|
+
verificationToken,
|
|
1784
|
+
userId: user.userId
|
|
1785
|
+
});
|
|
1786
|
+
onSuccess();
|
|
1787
|
+
resolve(res);
|
|
1788
|
+
} catch (error) {
|
|
1789
|
+
reject(error);
|
|
1790
|
+
}
|
|
1791
|
+
},
|
|
1792
|
+
...(!user?.userPhoneNumber && {
|
|
1793
|
+
title: title ?? "Connect a phone number"
|
|
1794
|
+
}),
|
|
1795
|
+
...(subTitle !== undefined && {
|
|
1796
|
+
subTitle
|
|
1797
|
+
}),
|
|
1798
|
+
...(params.formattedPhone && {
|
|
1799
|
+
formattedPhone: params.formattedPhone
|
|
1800
|
+
})
|
|
1801
|
+
}),
|
|
1802
|
+
showTitle: false
|
|
1803
|
+
});
|
|
1804
|
+
}), callbacks, "Failed to update phone number");
|
|
1805
|
+
}
|
|
1806
|
+
} catch (error) {
|
|
1807
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
1808
|
+
throw error;
|
|
1809
|
+
}
|
|
1810
|
+
throw new sdkTypes.TurnkeyError("Failed to initialize OTP for sms verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
|
|
1811
|
+
}
|
|
1812
|
+
};
|
|
1813
|
+
const handleUpdateUserEmail = async params => {
|
|
1814
|
+
const {
|
|
1815
|
+
successPageDuration = 2000,
|
|
1816
|
+
subTitle,
|
|
1817
|
+
title
|
|
1818
|
+
} = params || {};
|
|
1819
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1820
|
+
if (!session) {
|
|
1821
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
1822
|
+
}
|
|
1823
|
+
const onSuccess = () => {
|
|
1824
|
+
if (!successPageDuration) return;
|
|
1825
|
+
pushPage({
|
|
1826
|
+
key: "success",
|
|
1827
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
1828
|
+
text: "Email changed successfully!",
|
|
1829
|
+
duration: successPageDuration,
|
|
1830
|
+
onComplete: () => {
|
|
1831
|
+
closeModal();
|
|
1832
|
+
}
|
|
1833
|
+
}),
|
|
1834
|
+
preventBack: true,
|
|
1835
|
+
showTitle: false
|
|
1836
|
+
});
|
|
1837
|
+
};
|
|
1838
|
+
try {
|
|
1839
|
+
if (!params?.email && params?.email !== "") {
|
|
1840
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
1841
|
+
pushPage({
|
|
1842
|
+
key: "Update Email",
|
|
1843
|
+
content: jsxRuntime.jsx(UpdateEmail.UpdateEmail, {
|
|
1844
|
+
successPageDuration: successPageDuration,
|
|
1845
|
+
onSuccess: userId => {
|
|
1846
|
+
resolve(userId);
|
|
1847
|
+
},
|
|
1848
|
+
onError: error => reject(error),
|
|
1849
|
+
...(title !== undefined ? {
|
|
1850
|
+
title
|
|
1851
|
+
} : {}),
|
|
1852
|
+
...(subTitle !== undefined ? {
|
|
1853
|
+
subTitle
|
|
1854
|
+
} : {})
|
|
1855
|
+
}),
|
|
1856
|
+
showTitle: false
|
|
1857
|
+
});
|
|
1858
|
+
}));
|
|
1859
|
+
} else {
|
|
1860
|
+
const otpId = await initOtp({
|
|
1861
|
+
otpType: core.OtpType.Email,
|
|
1862
|
+
contact: params.email
|
|
1863
|
+
});
|
|
1864
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
1865
|
+
pushPage({
|
|
1866
|
+
key: "Update Email",
|
|
1867
|
+
content: jsxRuntime.jsx(OTP.OtpVerification, {
|
|
1868
|
+
otpType: core.OtpType.Email,
|
|
1869
|
+
contact: params.email,
|
|
1870
|
+
otpId: otpId,
|
|
1871
|
+
onContinue: async otpCode => {
|
|
1872
|
+
try {
|
|
1873
|
+
const {
|
|
1874
|
+
verificationToken
|
|
1875
|
+
} = await verifyOtp({
|
|
1876
|
+
otpId,
|
|
1877
|
+
otpCode,
|
|
1878
|
+
contact: params.email,
|
|
1879
|
+
otpType: core.OtpType.Email
|
|
1880
|
+
});
|
|
1881
|
+
const res = await updateUserEmail({
|
|
1882
|
+
email: params.email,
|
|
1883
|
+
verificationToken,
|
|
1884
|
+
userId: user.userId
|
|
1885
|
+
});
|
|
1886
|
+
onSuccess();
|
|
1887
|
+
resolve(res);
|
|
1888
|
+
} catch (error) {
|
|
1889
|
+
reject(error);
|
|
1890
|
+
}
|
|
1891
|
+
},
|
|
1892
|
+
...(!user?.userEmail && {
|
|
1893
|
+
title: title ?? "Connect an email"
|
|
1894
|
+
}),
|
|
1895
|
+
...(subTitle !== undefined && {
|
|
1896
|
+
subTitle
|
|
1897
|
+
})
|
|
1898
|
+
}),
|
|
1899
|
+
showTitle: false
|
|
1900
|
+
});
|
|
1901
|
+
}), callbacks, "Failed to update email");
|
|
1902
|
+
}
|
|
1903
|
+
} catch (error) {
|
|
1904
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
1905
|
+
throw error;
|
|
1906
|
+
}
|
|
1907
|
+
throw new sdkTypes.TurnkeyError("Failed to initialize OTP for email verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
|
|
1908
|
+
}
|
|
1909
|
+
};
|
|
1910
|
+
const handleAddEmail = async params => {
|
|
1911
|
+
const {
|
|
1912
|
+
successPageDuration = 2000,
|
|
1913
|
+
subTitle,
|
|
1914
|
+
title
|
|
1915
|
+
} = params || {};
|
|
1916
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1917
|
+
if (!session) {
|
|
1918
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
1919
|
+
}
|
|
1920
|
+
const onSuccess = () => {
|
|
1921
|
+
if (!successPageDuration) return;
|
|
1922
|
+
pushPage({
|
|
1923
|
+
key: "success",
|
|
1924
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
1925
|
+
text: "Email added successfully!",
|
|
1926
|
+
duration: successPageDuration,
|
|
1927
|
+
onComplete: () => {
|
|
1928
|
+
closeModal();
|
|
1929
|
+
}
|
|
1930
|
+
}),
|
|
1931
|
+
preventBack: true,
|
|
1932
|
+
showTitle: false
|
|
1933
|
+
});
|
|
1934
|
+
};
|
|
1935
|
+
try {
|
|
1936
|
+
if (!params?.email && params?.email !== "") {
|
|
1937
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
1938
|
+
pushPage({
|
|
1939
|
+
key: "Add Email",
|
|
1940
|
+
content: jsxRuntime.jsx(UpdateEmail.UpdateEmail, {
|
|
1941
|
+
successPageDuration: successPageDuration,
|
|
1942
|
+
onSuccess: userId => {
|
|
1943
|
+
resolve(userId);
|
|
1944
|
+
},
|
|
1945
|
+
onError: error => reject(error),
|
|
1946
|
+
...(!user?.userEmail ? {
|
|
1947
|
+
title: title ?? "Connect an email"
|
|
1948
|
+
} : {}),
|
|
1949
|
+
...(subTitle !== undefined ? {
|
|
1950
|
+
subTitle
|
|
1951
|
+
} : {})
|
|
1952
|
+
}),
|
|
1953
|
+
showTitle: false
|
|
1954
|
+
});
|
|
1955
|
+
}));
|
|
1956
|
+
} else {
|
|
1957
|
+
const otpId = await initOtp({
|
|
1958
|
+
otpType: core.OtpType.Email,
|
|
1959
|
+
contact: params.email
|
|
1960
|
+
});
|
|
1961
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
1962
|
+
pushPage({
|
|
1963
|
+
key: "Add Email",
|
|
1964
|
+
content: jsxRuntime.jsx(OTP.OtpVerification, {
|
|
1965
|
+
otpType: core.OtpType.Email,
|
|
1966
|
+
contact: params.email,
|
|
1967
|
+
otpId: otpId,
|
|
1968
|
+
onContinue: async otpCode => {
|
|
1969
|
+
try {
|
|
1970
|
+
const {
|
|
1971
|
+
verificationToken
|
|
1972
|
+
} = await verifyOtp({
|
|
1973
|
+
otpId,
|
|
1974
|
+
otpCode,
|
|
1975
|
+
contact: params.email,
|
|
1976
|
+
otpType: core.OtpType.Email
|
|
1977
|
+
});
|
|
1978
|
+
const res = await updateUserEmail({
|
|
1979
|
+
email: params.email,
|
|
1980
|
+
verificationToken,
|
|
1981
|
+
userId: user.userId
|
|
1982
|
+
});
|
|
1983
|
+
onSuccess();
|
|
1984
|
+
resolve(res);
|
|
1985
|
+
} catch (error) {
|
|
1986
|
+
reject(error);
|
|
1987
|
+
}
|
|
1988
|
+
},
|
|
1989
|
+
...(!user?.userEmail && {
|
|
1990
|
+
title: title ?? "Connect an email"
|
|
1991
|
+
}),
|
|
1992
|
+
...(subTitle !== undefined && {
|
|
1993
|
+
subTitle
|
|
1994
|
+
})
|
|
1995
|
+
}),
|
|
1996
|
+
showTitle: false
|
|
1997
|
+
});
|
|
1998
|
+
}), callbacks, "Failed to add email");
|
|
1999
|
+
}
|
|
2000
|
+
} catch (error) {
|
|
2001
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
2002
|
+
throw error;
|
|
2003
|
+
}
|
|
2004
|
+
throw new sdkTypes.TurnkeyError("Failed to initialize OTP for email verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
|
|
2005
|
+
}
|
|
2006
|
+
};
|
|
2007
|
+
const handleAddPhoneNumber = async params => {
|
|
2008
|
+
const {
|
|
2009
|
+
successPageDuration = 2000,
|
|
2010
|
+
subTitle,
|
|
2011
|
+
title
|
|
2012
|
+
} = params || {};
|
|
2013
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2014
|
+
if (!session) {
|
|
2015
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
2016
|
+
}
|
|
2017
|
+
if (!masterConfig) {
|
|
2018
|
+
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.CONFIG_NOT_INITIALIZED);
|
|
2019
|
+
}
|
|
2020
|
+
if (!masterConfig.auth?.methods?.smsOtpAuthEnabled) {
|
|
2021
|
+
throw new sdkTypes.TurnkeyError("SMS OTP authentication is not enabled in the configuration.", sdkTypes.TurnkeyErrorCodes.AUTH_METHOD_NOT_ENABLED);
|
|
2022
|
+
}
|
|
2023
|
+
const onSuccess = () => {
|
|
2024
|
+
if (!successPageDuration) return;
|
|
2025
|
+
pushPage({
|
|
2026
|
+
key: "success",
|
|
2027
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
2028
|
+
text: "Phone number updated successfully!",
|
|
2029
|
+
duration: successPageDuration,
|
|
2030
|
+
onComplete: () => {
|
|
2031
|
+
closeModal();
|
|
2032
|
+
}
|
|
2033
|
+
}),
|
|
2034
|
+
preventBack: true,
|
|
2035
|
+
showTitle: false
|
|
2036
|
+
});
|
|
2037
|
+
};
|
|
2038
|
+
try {
|
|
2039
|
+
if (!params?.phoneNumber && params?.phoneNumber !== "") {
|
|
2040
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2041
|
+
pushPage({
|
|
2042
|
+
key: "Add Phone Number",
|
|
2043
|
+
content: jsxRuntime.jsx(UpdatePhoneNumber.UpdatePhoneNumber, {
|
|
2044
|
+
successPageDuration: successPageDuration,
|
|
2045
|
+
onSuccess: userId => {
|
|
2046
|
+
resolve(userId);
|
|
2047
|
+
},
|
|
2048
|
+
onError: error => {
|
|
2049
|
+
reject(error);
|
|
2050
|
+
},
|
|
2051
|
+
...(!user?.userPhoneNumber && {
|
|
2052
|
+
title: title ?? "Connect a phone number"
|
|
2053
|
+
}),
|
|
2054
|
+
...(subTitle !== undefined && {
|
|
2055
|
+
subTitle
|
|
2056
|
+
})
|
|
2057
|
+
}),
|
|
2058
|
+
showTitle: false
|
|
2059
|
+
});
|
|
2060
|
+
}), callbacks, "Failed to add phone number");
|
|
2061
|
+
} else {
|
|
2062
|
+
const otpId = await initOtp({
|
|
2063
|
+
otpType: core.OtpType.Sms,
|
|
2064
|
+
contact: params.phoneNumber
|
|
2065
|
+
});
|
|
2066
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2067
|
+
pushPage({
|
|
2068
|
+
key: "Add Phone Number",
|
|
2069
|
+
content: jsxRuntime.jsx(OTP.OtpVerification, {
|
|
2070
|
+
otpType: core.OtpType.Sms,
|
|
2071
|
+
contact: params.phoneNumber,
|
|
2072
|
+
otpId: otpId,
|
|
2073
|
+
onContinue: async otpCode => {
|
|
2074
|
+
try {
|
|
2075
|
+
const {
|
|
2076
|
+
verificationToken
|
|
2077
|
+
} = await verifyOtp({
|
|
2078
|
+
otpId,
|
|
2079
|
+
otpCode,
|
|
2080
|
+
contact: params.phoneNumber,
|
|
2081
|
+
otpType: core.OtpType.Sms
|
|
2082
|
+
});
|
|
2083
|
+
const res = await updateUserPhoneNumber({
|
|
2084
|
+
phoneNumber: params.phoneNumber,
|
|
2085
|
+
verificationToken,
|
|
2086
|
+
userId: user.userId
|
|
2087
|
+
});
|
|
2088
|
+
onSuccess();
|
|
2089
|
+
resolve(res);
|
|
2090
|
+
} catch (error) {
|
|
2091
|
+
reject(error);
|
|
2092
|
+
}
|
|
2093
|
+
},
|
|
2094
|
+
...(!user?.userPhoneNumber && {
|
|
2095
|
+
title: title ?? "Connect a phone number"
|
|
2096
|
+
}),
|
|
2097
|
+
...(subTitle !== undefined && {
|
|
2098
|
+
subTitle
|
|
2099
|
+
}),
|
|
2100
|
+
...(params.formattedPhone && {
|
|
2101
|
+
formattedPhone: params.formattedPhone
|
|
2102
|
+
})
|
|
2103
|
+
}),
|
|
2104
|
+
showTitle: false
|
|
2105
|
+
});
|
|
2106
|
+
}), callbacks, "Failed to add phone number");
|
|
2107
|
+
}
|
|
2108
|
+
} catch (error) {
|
|
2109
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
2110
|
+
throw error;
|
|
2111
|
+
}
|
|
2112
|
+
throw new sdkTypes.TurnkeyError("Failed to initialize OTP for sms verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
|
|
2113
|
+
}
|
|
2114
|
+
};
|
|
2115
|
+
const handleRemovePasskey = async params => {
|
|
2116
|
+
const {
|
|
2117
|
+
authenticatorId,
|
|
2118
|
+
successPageDuration = 2000,
|
|
2119
|
+
subTitle,
|
|
2120
|
+
title,
|
|
2121
|
+
stampWith,
|
|
2122
|
+
userId
|
|
2123
|
+
} = params;
|
|
2124
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2125
|
+
if (!session) {
|
|
2126
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
2127
|
+
}
|
|
2128
|
+
return utils.withTurnkeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2129
|
+
pushPage({
|
|
2130
|
+
key: "Remove Passkey",
|
|
2131
|
+
content: jsxRuntime.jsx(RemovePasskey.RemovePasskey, {
|
|
2132
|
+
authenticatorId: authenticatorId,
|
|
2133
|
+
successPageDuration: successPageDuration,
|
|
2134
|
+
onSuccess: authenticatorIds => {
|
|
2135
|
+
resolve(authenticatorIds);
|
|
2136
|
+
},
|
|
2137
|
+
onError: error => {
|
|
2138
|
+
reject(error);
|
|
2139
|
+
},
|
|
2140
|
+
stampWith: stampWith,
|
|
2141
|
+
...(userId && {
|
|
2142
|
+
userId
|
|
2143
|
+
}),
|
|
2144
|
+
...(title !== undefined && {
|
|
2145
|
+
title
|
|
2146
|
+
}),
|
|
2147
|
+
...(subTitle !== undefined && {
|
|
2148
|
+
subTitle
|
|
2149
|
+
})
|
|
2150
|
+
}),
|
|
2151
|
+
showTitle: false,
|
|
2152
|
+
preventBack: true
|
|
2153
|
+
});
|
|
2154
|
+
}), callbacks, "Failed to remove passkey");
|
|
2155
|
+
};
|
|
2156
|
+
const handleAddPasskey = async params => {
|
|
2157
|
+
const {
|
|
2158
|
+
name,
|
|
2159
|
+
displayName,
|
|
2160
|
+
successPageDuration = 2000,
|
|
2161
|
+
stampWith
|
|
2162
|
+
} = params || {};
|
|
2163
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2164
|
+
if (!session) {
|
|
2165
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
2166
|
+
}
|
|
2167
|
+
const userId = params?.userId || session.userId;
|
|
2168
|
+
try {
|
|
2169
|
+
const resPromise = addPasskey({
|
|
2170
|
+
...(name && {
|
|
2171
|
+
name
|
|
2172
|
+
}),
|
|
2173
|
+
...(displayName && {
|
|
2174
|
+
displayName
|
|
2175
|
+
}),
|
|
2176
|
+
userId,
|
|
2177
|
+
stampWith
|
|
2178
|
+
});
|
|
2179
|
+
resPromise.then(() => {
|
|
2180
|
+
pushPage({
|
|
2181
|
+
key: "Passkey Added",
|
|
2182
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
2183
|
+
text: "Successfully added passkey!",
|
|
2184
|
+
duration: successPageDuration,
|
|
2185
|
+
onComplete: () => {
|
|
2186
|
+
closeModal();
|
|
2187
|
+
}
|
|
2188
|
+
}),
|
|
2189
|
+
preventBack: true,
|
|
2190
|
+
showTitle: false
|
|
2191
|
+
});
|
|
2192
|
+
});
|
|
2193
|
+
return await resPromise;
|
|
2194
|
+
} catch (error) {
|
|
2195
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
2196
|
+
throw error;
|
|
2197
|
+
}
|
|
2198
|
+
throw new sdkTypes.TurnkeyError("Failed to add passkey in handler.", sdkTypes.TurnkeyErrorCodes.ADD_PASSKEY_ERROR, error);
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
const handleRemoveOauthProvider = async params => {
|
|
2202
|
+
const {
|
|
2203
|
+
providerId,
|
|
2204
|
+
successPageDuration = 2000,
|
|
2205
|
+
subTitle,
|
|
2206
|
+
title,
|
|
2207
|
+
stampWith
|
|
2208
|
+
} = params;
|
|
2209
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2210
|
+
if (!session) {
|
|
2211
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
2212
|
+
}
|
|
2213
|
+
try {
|
|
2214
|
+
return new Promise((resolve, reject) => {
|
|
2215
|
+
pushPage({
|
|
2216
|
+
key: "Remove OAuth Provider",
|
|
2217
|
+
content: jsxRuntime.jsx(RemoveOAuthProvider.RemoveOAuthProvider, {
|
|
2218
|
+
providerId: providerId,
|
|
2219
|
+
stampWith: stampWith,
|
|
2220
|
+
successPageDuration: successPageDuration,
|
|
2221
|
+
onSuccess: providerIds => {
|
|
2222
|
+
resolve(providerIds);
|
|
2223
|
+
},
|
|
2224
|
+
onError: error => {
|
|
2225
|
+
reject(error);
|
|
2226
|
+
},
|
|
2227
|
+
...(title !== undefined && {
|
|
2228
|
+
title
|
|
2229
|
+
}),
|
|
2230
|
+
...(subTitle !== undefined && {
|
|
2231
|
+
subTitle
|
|
2232
|
+
})
|
|
2233
|
+
}),
|
|
2234
|
+
showTitle: false,
|
|
2235
|
+
preventBack: true
|
|
2236
|
+
});
|
|
2237
|
+
});
|
|
2238
|
+
} catch (error) {
|
|
2239
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
2240
|
+
throw error;
|
|
2241
|
+
}
|
|
2242
|
+
throw new sdkTypes.TurnkeyError("Failed to remove OAuth provider in handler.", sdkTypes.TurnkeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR, error);
|
|
2243
|
+
}
|
|
2244
|
+
};
|
|
2245
|
+
const handleAddOauthProvider = async params => {
|
|
2246
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2247
|
+
if (!session) {
|
|
2248
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
2249
|
+
}
|
|
2250
|
+
const {
|
|
2251
|
+
providerName,
|
|
2252
|
+
stampWith
|
|
2253
|
+
} = params;
|
|
2254
|
+
const onOauthSuccess = async params => {
|
|
2255
|
+
await addOauthProvider({
|
|
2256
|
+
providerName: params.providerName,
|
|
2257
|
+
oidcToken: params.oidcToken,
|
|
2258
|
+
stampWith
|
|
2259
|
+
});
|
|
2260
|
+
pushPage({
|
|
2261
|
+
key: "OAuth Provider Added",
|
|
2262
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
2263
|
+
text: `Successfully added ${params.providerName} OAuth provider!`,
|
|
2264
|
+
duration: 3000,
|
|
2265
|
+
onComplete: () => {
|
|
2266
|
+
closeModal();
|
|
2267
|
+
}
|
|
2268
|
+
}),
|
|
2269
|
+
preventBack: true,
|
|
2270
|
+
showTitle: false
|
|
2271
|
+
});
|
|
2272
|
+
};
|
|
2273
|
+
switch (providerName) {
|
|
2274
|
+
case sdkTypes.OAuthProviders.GOOGLE:
|
|
2275
|
+
{
|
|
2276
|
+
await handleGoogleOauth({
|
|
2277
|
+
openInPage: false,
|
|
2278
|
+
onOauthSuccess
|
|
2279
|
+
});
|
|
2280
|
+
break;
|
|
2281
|
+
}
|
|
2282
|
+
case sdkTypes.OAuthProviders.APPLE:
|
|
2283
|
+
{
|
|
2284
|
+
await handleAppleOauth({
|
|
2285
|
+
openInPage: false,
|
|
2286
|
+
onOauthSuccess
|
|
2287
|
+
});
|
|
2288
|
+
break;
|
|
2289
|
+
}
|
|
2290
|
+
case sdkTypes.OAuthProviders.FACEBOOK:
|
|
2291
|
+
{
|
|
2292
|
+
await handleFacebookOauth({
|
|
2293
|
+
openInPage: false,
|
|
2294
|
+
onOauthSuccess
|
|
2295
|
+
});
|
|
2296
|
+
break;
|
|
2297
|
+
}
|
|
2298
|
+
default:
|
|
2299
|
+
{
|
|
2300
|
+
throw new sdkTypes.TurnkeyError(`Unsupported OAuth provider: ${providerName}`, sdkTypes.TurnkeyErrorCodes.NOT_FOUND);
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
};
|
|
2304
|
+
const handleLinkExternalWallet = async params => {
|
|
2305
|
+
const {
|
|
2306
|
+
successPageDuration = 2000
|
|
2307
|
+
} = params || {};
|
|
2308
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2309
|
+
if (!session) {
|
|
2310
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
2311
|
+
}
|
|
2312
|
+
if (!masterConfig?.walletConfig?.features?.connecting) {
|
|
2313
|
+
throw new sdkTypes.TurnkeyError("Wallet connecting is not enabled.", sdkTypes.TurnkeyErrorCodes.FEATURE_NOT_ENABLED);
|
|
2314
|
+
}
|
|
2315
|
+
const providers = await getWalletProviders();
|
|
2316
|
+
pushPage({
|
|
2317
|
+
key: "Link Wallet",
|
|
2318
|
+
content: jsxRuntime.jsx(LinkWallet.LinkWalletModal, {
|
|
2319
|
+
providers: providers,
|
|
2320
|
+
successPageDuration: successPageDuration
|
|
2321
|
+
})
|
|
2322
|
+
});
|
|
2323
|
+
};
|
|
2324
|
+
const handleRemoveUserEmail = async params => {
|
|
2325
|
+
const {
|
|
2326
|
+
successPageDuration = 2000,
|
|
2327
|
+
stampWith,
|
|
2328
|
+
userId
|
|
2329
|
+
} = params || {};
|
|
2330
|
+
if (!session) {
|
|
2331
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
2332
|
+
}
|
|
2333
|
+
try {
|
|
2334
|
+
return new Promise((resolve, reject) => {
|
|
2335
|
+
pushPage({
|
|
2336
|
+
key: "Remove Email",
|
|
2337
|
+
content: jsxRuntime.jsx(RemoveEmail.RemoveEmail, {
|
|
2338
|
+
successPageDuration: successPageDuration,
|
|
2339
|
+
...(userId && {
|
|
2340
|
+
userId
|
|
2341
|
+
}),
|
|
2342
|
+
...(stampWith && {
|
|
2343
|
+
stampWith
|
|
2344
|
+
}),
|
|
2345
|
+
onSuccess: userId => {
|
|
2346
|
+
resolve(userId);
|
|
2347
|
+
},
|
|
2348
|
+
onError: error => {
|
|
2349
|
+
reject(error);
|
|
2350
|
+
}
|
|
2351
|
+
}),
|
|
2352
|
+
showTitle: false,
|
|
2353
|
+
preventBack: true
|
|
2354
|
+
});
|
|
2355
|
+
});
|
|
2356
|
+
} catch (error) {
|
|
2357
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
2358
|
+
throw error;
|
|
2359
|
+
}
|
|
2360
|
+
throw new sdkTypes.TurnkeyError("Failed to remove user email.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_EMAIL_ERROR, error);
|
|
2361
|
+
}
|
|
2362
|
+
};
|
|
2363
|
+
const handleRemoveUserPhoneNumber = async params => {
|
|
2364
|
+
const {
|
|
2365
|
+
successPageDuration = 2000,
|
|
2366
|
+
stampWith,
|
|
2367
|
+
userId
|
|
2368
|
+
} = params || {};
|
|
2369
|
+
if (!session) {
|
|
2370
|
+
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
2371
|
+
}
|
|
2372
|
+
try {
|
|
2373
|
+
return new Promise((resolve, reject) => {
|
|
2374
|
+
pushPage({
|
|
2375
|
+
key: "Remove Phone Number",
|
|
2376
|
+
content: jsxRuntime.jsx(RemovePhoneNumber.RemovePhoneNumber, {
|
|
2377
|
+
successPageDuration: successPageDuration,
|
|
2378
|
+
...(userId && {
|
|
2379
|
+
userId
|
|
2380
|
+
}),
|
|
2381
|
+
...(stampWith && {
|
|
2382
|
+
stampWith
|
|
2383
|
+
}),
|
|
2384
|
+
onSuccess: userId => {
|
|
2385
|
+
resolve(userId);
|
|
2386
|
+
},
|
|
2387
|
+
onError: error => {
|
|
2388
|
+
reject(error);
|
|
2389
|
+
}
|
|
2390
|
+
}),
|
|
2391
|
+
showTitle: false,
|
|
2392
|
+
preventBack: true
|
|
2393
|
+
});
|
|
2394
|
+
});
|
|
2395
|
+
} catch (error) {
|
|
2396
|
+
if (error instanceof sdkTypes.TurnkeyError) {
|
|
2397
|
+
throw error;
|
|
2398
|
+
}
|
|
2399
|
+
throw new sdkTypes.TurnkeyError("Failed to remove user phone number.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR, error);
|
|
2400
|
+
}
|
|
2401
|
+
};
|
|
2402
|
+
return jsxRuntime.jsx(Types.ClientContext.Provider, {
|
|
2403
|
+
value: {
|
|
2404
|
+
session,
|
|
2405
|
+
allSessions,
|
|
2406
|
+
clientState,
|
|
2407
|
+
authState,
|
|
2408
|
+
user,
|
|
2409
|
+
wallets,
|
|
2410
|
+
config: masterConfig,
|
|
2411
|
+
httpClient: client?.httpClient,
|
|
2412
|
+
createPasskey,
|
|
2413
|
+
logout,
|
|
2414
|
+
loginWithPasskey,
|
|
2415
|
+
signUpWithPasskey,
|
|
2416
|
+
getWalletProviders,
|
|
2417
|
+
connectWalletAccount,
|
|
2418
|
+
disconnectWalletAccount,
|
|
2419
|
+
switchWalletProviderChain,
|
|
2420
|
+
loginWithWallet,
|
|
2421
|
+
signUpWithWallet,
|
|
2422
|
+
loginOrSignupWithWallet,
|
|
2423
|
+
initOtp,
|
|
2424
|
+
verifyOtp,
|
|
2425
|
+
loginWithOtp,
|
|
2426
|
+
signUpWithOtp,
|
|
2427
|
+
completeOtp,
|
|
2428
|
+
loginWithOauth,
|
|
2429
|
+
signUpWithOauth,
|
|
2430
|
+
completeOauth,
|
|
2431
|
+
fetchWallets,
|
|
2432
|
+
fetchWalletAccounts,
|
|
2433
|
+
refreshWallets,
|
|
2434
|
+
signMessage,
|
|
2435
|
+
signTransaction,
|
|
2436
|
+
signAndSendTransaction,
|
|
2437
|
+
fetchUser,
|
|
2438
|
+
refreshUser,
|
|
2439
|
+
updateUserEmail,
|
|
2440
|
+
removeUserEmail,
|
|
2441
|
+
updateUserPhoneNumber,
|
|
2442
|
+
removeUserPhoneNumber,
|
|
2443
|
+
updateUserName,
|
|
2444
|
+
addOauthProvider,
|
|
2445
|
+
removeOauthProviders,
|
|
2446
|
+
addPasskey,
|
|
2447
|
+
removePasskeys,
|
|
2448
|
+
createWallet,
|
|
2449
|
+
createWalletAccounts,
|
|
2450
|
+
exportWallet,
|
|
2451
|
+
importWallet,
|
|
2452
|
+
deleteSubOrganization,
|
|
2453
|
+
storeSession,
|
|
2454
|
+
clearSession,
|
|
2455
|
+
clearAllSessions,
|
|
2456
|
+
refreshSession,
|
|
2457
|
+
getSession,
|
|
2458
|
+
getAllSessions,
|
|
2459
|
+
setActiveSession,
|
|
2460
|
+
clearUnusedKeyPairs,
|
|
2461
|
+
getActiveSessionKey,
|
|
2462
|
+
createApiKeyPair,
|
|
2463
|
+
getProxyAuthConfig,
|
|
2464
|
+
handleLogin,
|
|
2465
|
+
handleGoogleOauth,
|
|
2466
|
+
handleAppleOauth,
|
|
2467
|
+
handleFacebookOauth,
|
|
2468
|
+
handleExport,
|
|
2469
|
+
handleImport,
|
|
2470
|
+
handleUpdateUserEmail,
|
|
2471
|
+
handleUpdateUserPhoneNumber,
|
|
2472
|
+
handleUpdateUserName,
|
|
2473
|
+
handleAddOauthProvider,
|
|
2474
|
+
handleRemoveOauthProvider,
|
|
2475
|
+
handleAddPasskey,
|
|
2476
|
+
handleRemovePasskey,
|
|
2477
|
+
handleAddEmail,
|
|
2478
|
+
handleAddPhoneNumber,
|
|
2479
|
+
handleSignMessage,
|
|
2480
|
+
handleLinkExternalWallet,
|
|
2481
|
+
handleRemoveUserEmail,
|
|
2482
|
+
handleRemoveUserPhoneNumber
|
|
2483
|
+
},
|
|
2484
|
+
children: children
|
|
2485
|
+
});
|
|
2486
|
+
};
|
|
2487
|
+
|
|
2488
|
+
exports.ClientProvider = ClientProvider;
|
|
2489
|
+
//# sourceMappingURL=Provider.js.map
|