@turnkey/react-wallet-kit 1.0.0-beta.2 → 1.0.0-beta.5
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/README.MD +2 -1
- package/dist/components/auth/Wallet.js +3 -3
- package/dist/components/auth/Wallet.js.map +1 -1
- package/dist/components/auth/Wallet.mjs +6 -6
- package/dist/components/auth/Wallet.mjs.map +1 -1
- package/dist/components/export/Export.d.ts +2 -2
- package/dist/components/export/Export.d.ts.map +1 -1
- package/dist/components/export/Export.js +10 -3
- package/dist/components/export/Export.js.map +1 -1
- package/dist/components/export/Export.mjs +11 -4
- package/dist/components/export/Export.mjs.map +1 -1
- package/dist/components/export/ExportWarning.d.ts +2 -2
- package/dist/components/export/ExportWarning.d.ts.map +1 -1
- package/dist/components/export/ExportWarning.js +54 -14
- package/dist/components/export/ExportWarning.js.map +1 -1
- package/dist/components/export/ExportWarning.mjs +73 -22
- package/dist/components/export/ExportWarning.mjs.map +1 -1
- package/dist/components/import/Import.d.ts +0 -4
- package/dist/components/import/Import.d.ts.map +1 -1
- package/dist/components/import/Import.js +0 -5
- package/dist/components/import/Import.js.map +1 -1
- package/dist/components/import/Import.mjs +1 -6
- package/dist/components/import/Import.mjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/providers/TurnkeyProvider.d.ts +1 -0
- package/dist/providers/TurnkeyProvider.d.ts.map +1 -1
- package/dist/providers/TurnkeyProvider.js +1 -0
- package/dist/providers/TurnkeyProvider.js.map +1 -1
- package/dist/providers/TurnkeyProvider.mjs +1 -0
- package/dist/providers/TurnkeyProvider.mjs.map +1 -1
- package/dist/providers/client/Hook.d.ts +1 -0
- package/dist/providers/client/Hook.d.ts.map +1 -1
- package/dist/providers/client/Hook.js +1 -0
- package/dist/providers/client/Hook.js.map +1 -1
- package/dist/providers/client/Hook.mjs +1 -0
- package/dist/providers/client/Hook.mjs.map +1 -1
- package/dist/providers/client/Provider.d.ts.map +1 -1
- package/dist/providers/client/Provider.js +428 -290
- package/dist/providers/client/Provider.js.map +1 -1
- package/dist/providers/client/Provider.mjs +2006 -1818
- package/dist/providers/client/Provider.mjs.map +1 -1
- package/dist/providers/client/Types.d.ts +96 -45
- package/dist/providers/client/Types.d.ts.map +1 -1
- package/dist/providers/client/Types.js +1 -0
- package/dist/providers/client/Types.js.map +1 -1
- package/dist/providers/client/Types.mjs +1 -0
- package/dist/providers/client/Types.mjs.map +1 -1
- package/dist/providers/modal/Hook.d.ts +1 -0
- package/dist/providers/modal/Hook.d.ts.map +1 -1
- package/dist/providers/modal/Hook.js +1 -0
- package/dist/providers/modal/Hook.js.map +1 -1
- package/dist/providers/modal/Hook.mjs +1 -0
- package/dist/providers/modal/Hook.mjs.map +1 -1
- package/dist/providers/modal/Root.d.ts.map +1 -1
- package/dist/providers/modal/Root.js +40 -24
- package/dist/providers/modal/Root.js.map +1 -1
- package/dist/providers/modal/Root.mjs +39 -27
- package/dist/providers/modal/Root.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/base.d.ts +59 -1
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/base.js +13 -0
- package/dist/types/base.js.map +1 -1
- package/dist/types/base.mjs +13 -0
- package/dist/types/base.mjs.map +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +31 -2
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +38 -4
- package/dist/utils.mjs.map +1 -1
- package/package.json +12 -4
|
@@ -62,12 +62,14 @@ const ClientProvider = ({
|
|
|
62
62
|
}) => {
|
|
63
63
|
const [client, setClient] = react.useState(undefined);
|
|
64
64
|
const [session, setSession] = react.useState(undefined);
|
|
65
|
-
const [autoRefreshSession, setAutoRefreshSession] = react.useState(false);
|
|
66
65
|
const [masterConfig, setMasterConfig] = react.useState(undefined);
|
|
67
66
|
const [wallets, setWallets] = react.useState([]);
|
|
68
67
|
const [user, setUser] = react.useState(undefined);
|
|
69
68
|
const [clientState, setClientState] = react.useState();
|
|
70
69
|
const [authState, setAuthState] = react.useState(base.AuthState.Unauthenticated);
|
|
70
|
+
// we use this custom hook to only update the state if the value is different
|
|
71
|
+
// this is so our useEffect that calls `initializeWalletProviderListeners()` only runs when it needs to
|
|
72
|
+
const [walletProviders, setWalletProviders] = utils.useWalletProviderState();
|
|
71
73
|
const expiryTimeoutsRef = react.useRef({});
|
|
72
74
|
const proxyAuthConfigRef = react.useRef(null);
|
|
73
75
|
const [allSessions, setAllSessions] = react.useState(undefined);
|
|
@@ -75,78 +77,6 @@ const ClientProvider = ({
|
|
|
75
77
|
pushPage,
|
|
76
78
|
closeModal
|
|
77
79
|
} = 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
80
|
const completeRedirectOauth = async () => {
|
|
151
81
|
// Check for either hash or search parameters that could indicate an OAuth redirect
|
|
152
82
|
if (window.location.hash || window.location.search) {
|
|
@@ -312,7 +242,8 @@ const ClientProvider = ({
|
|
|
312
242
|
},
|
|
313
243
|
sessionExpirationSeconds: proxyAuthConfig?.sessionExpirationSeconds,
|
|
314
244
|
methodOrder,
|
|
315
|
-
oauthOrder
|
|
245
|
+
oauthOrder,
|
|
246
|
+
autoRefreshSession: config.auth?.autoRefreshSession ?? true
|
|
316
247
|
},
|
|
317
248
|
walletConfig: {
|
|
318
249
|
...config.walletConfig,
|
|
@@ -327,11 +258,13 @@ const ClientProvider = ({
|
|
|
327
258
|
...config.walletConfig?.chains,
|
|
328
259
|
ethereum: {
|
|
329
260
|
...config.walletConfig?.chains?.ethereum,
|
|
330
|
-
|
|
261
|
+
// keep user's value if provided; default only when undefined
|
|
262
|
+
native: config.walletConfig?.chains?.ethereum?.native ?? true
|
|
331
263
|
},
|
|
332
264
|
solana: {
|
|
333
265
|
...config.walletConfig?.chains?.solana,
|
|
334
|
-
|
|
266
|
+
// keep user's value if provided; default only when undefined
|
|
267
|
+
native: config.walletConfig?.chains?.solana?.native ?? true
|
|
335
268
|
}
|
|
336
269
|
}
|
|
337
270
|
},
|
|
@@ -375,7 +308,6 @@ const ClientProvider = ({
|
|
|
375
308
|
})
|
|
376
309
|
}
|
|
377
310
|
});
|
|
378
|
-
setAutoRefreshSession(masterConfig?.auth?.autoRefreshSession ?? false);
|
|
379
311
|
await turnkeyClient.init();
|
|
380
312
|
setClient(turnkeyClient);
|
|
381
313
|
// Don't set clientState to ready until we fetch the proxy auth config (See other fetchProxyAuthConfig useEffect)
|
|
@@ -393,17 +325,21 @@ const ClientProvider = ({
|
|
|
393
325
|
* @internal
|
|
394
326
|
*/
|
|
395
327
|
const initializeSessions = async () => {
|
|
328
|
+
setSession(undefined);
|
|
329
|
+
setAllSessions(undefined);
|
|
396
330
|
try {
|
|
397
|
-
const
|
|
398
|
-
if (!
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
await Promise.all(Object.keys(allSessions).map(async sessionKey => {
|
|
402
|
-
const session = allSessions?.[sessionKey];
|
|
331
|
+
const allLocalStorageSessions = await getAllSessions();
|
|
332
|
+
if (!allLocalStorageSessions) return;
|
|
333
|
+
await Promise.all(Object.keys(allLocalStorageSessions).map(async sessionKey => {
|
|
334
|
+
const session = allLocalStorageSessions?.[sessionKey];
|
|
403
335
|
if (!utils.isValidSession(session)) {
|
|
404
336
|
await clearSession({
|
|
405
337
|
sessionKey
|
|
406
338
|
});
|
|
339
|
+
if (sessionKey === (await getActiveSessionKey())) {
|
|
340
|
+
setSession(undefined);
|
|
341
|
+
}
|
|
342
|
+
delete allLocalStorageSessions[sessionKey];
|
|
407
343
|
return;
|
|
408
344
|
}
|
|
409
345
|
scheduleSessionExpiration({
|
|
@@ -411,10 +347,14 @@ const ClientProvider = ({
|
|
|
411
347
|
expiry: session.expiry
|
|
412
348
|
});
|
|
413
349
|
}));
|
|
414
|
-
setAllSessions(
|
|
350
|
+
setAllSessions(allLocalStorageSessions || undefined);
|
|
415
351
|
const activeSessionKey = await client?.getActiveSessionKey();
|
|
416
352
|
if (activeSessionKey) {
|
|
417
|
-
|
|
353
|
+
// If we have an active session key, set
|
|
354
|
+
if (!allLocalStorageSessions[activeSessionKey]) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
setSession(allLocalStorageSessions[activeSessionKey]);
|
|
418
358
|
await refreshUser();
|
|
419
359
|
await refreshWallets();
|
|
420
360
|
return;
|
|
@@ -427,6 +367,79 @@ const ClientProvider = ({
|
|
|
427
367
|
}
|
|
428
368
|
}
|
|
429
369
|
};
|
|
370
|
+
/**
|
|
371
|
+
* @internal
|
|
372
|
+
* Attach listeners for connected wallet providers so we can refresh state on changes.
|
|
373
|
+
*
|
|
374
|
+
* - Ethereum: listens for disconnect and chain switches to trigger a refresh.
|
|
375
|
+
* - Solana: listens for disconnect via Wallet Standard `change` events to trigger a refresh.
|
|
376
|
+
* - WalletConnect: listens for disconnect via our custom wrapper’s `change` event to trigger a refresh.
|
|
377
|
+
*
|
|
378
|
+
* Notes:
|
|
379
|
+
* - Only providers that are connected are bound.
|
|
380
|
+
* - WalletConnect is excluded from the “native” paths and handled via its unified `change` event.
|
|
381
|
+
*
|
|
382
|
+
* @param walletProviders - Discovered providers; only connected ones are bound.
|
|
383
|
+
* @param onWalletsChanged - Invoked when a relevant provider event occurs.
|
|
384
|
+
* @returns Cleanup function that removes all listeners registered by this call.
|
|
385
|
+
*/
|
|
386
|
+
async function initializeWalletProviderListeners(walletProviders, onWalletsChanged) {
|
|
387
|
+
if (walletProviders.length === 0) return () => {};
|
|
388
|
+
const cleanups = [];
|
|
389
|
+
// we only want to initialize these listeners for connected walletProviders
|
|
390
|
+
const nativeOnly = provider => provider.interfaceType !== core.WalletInterfaceType.WalletConnect;
|
|
391
|
+
const ethProviders = masterConfig?.walletConfig?.chains.ethereum?.native ? walletProviders.filter(provider => provider.chainInfo.namespace === core.Chain.Ethereum && nativeOnly(provider) && provider.connectedAddresses.length > 0) : [];
|
|
392
|
+
const solProviders = masterConfig?.walletConfig?.chains.solana?.native ? walletProviders.filter(provider => provider.chainInfo.namespace === core.Chain.Solana && nativeOnly(provider) && provider.connectedAddresses.length > 0) : [];
|
|
393
|
+
// we exclude WalletConnect from the native event wiring
|
|
394
|
+
// this is because WC is handled separately with a custom wrapper’s
|
|
395
|
+
// `change` event
|
|
396
|
+
const wcProviders = walletProviders.filter(p => p.interfaceType === core.WalletInterfaceType.WalletConnect && p.connectedAddresses.length > 0);
|
|
397
|
+
function attachEthereumListeners(provider, onWalletsChanged) {
|
|
398
|
+
if (typeof provider.on !== "function") return;
|
|
399
|
+
const handleChainChanged = _chainId => onWalletsChanged();
|
|
400
|
+
const handleAccountsChanged = accounts => {
|
|
401
|
+
if (accounts.length === 0) onWalletsChanged();
|
|
402
|
+
};
|
|
403
|
+
const handleDisconnect = () => onWalletsChanged();
|
|
404
|
+
provider.on("chainChanged", handleChainChanged);
|
|
405
|
+
provider.on("accountsChanged", handleAccountsChanged);
|
|
406
|
+
provider.on("disconnect", handleDisconnect);
|
|
407
|
+
return () => {
|
|
408
|
+
provider.removeListener("chainChanged", handleChainChanged);
|
|
409
|
+
provider.removeListener("accountsChanged", handleAccountsChanged);
|
|
410
|
+
provider.removeListener("disconnect", handleDisconnect);
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
function attachSolanaListeners(provider, onWalletsChanged) {
|
|
414
|
+
const cleanups = [];
|
|
415
|
+
const walletEvents = provider?.features?.["standard:events"];
|
|
416
|
+
if (walletEvents?.on) {
|
|
417
|
+
const offChange = walletEvents.on("change", _evt => {
|
|
418
|
+
onWalletsChanged();
|
|
419
|
+
});
|
|
420
|
+
cleanups.push(offChange);
|
|
421
|
+
}
|
|
422
|
+
return () => cleanups.forEach(fn => fn());
|
|
423
|
+
}
|
|
424
|
+
ethProviders.forEach(p => {
|
|
425
|
+
const cleanup = attachEthereumListeners(p.provider, onWalletsChanged);
|
|
426
|
+
if (cleanup) cleanups.push(cleanup);
|
|
427
|
+
});
|
|
428
|
+
solProviders.forEach(p => {
|
|
429
|
+
const cleanup = attachSolanaListeners(p.provider, onWalletsChanged);
|
|
430
|
+
if (cleanup) cleanups.push(cleanup);
|
|
431
|
+
});
|
|
432
|
+
wcProviders.forEach(p => {
|
|
433
|
+
const standardEvents = p.provider?.features?.["standard:events"];
|
|
434
|
+
if (standardEvents?.on) {
|
|
435
|
+
const unsubscribe = standardEvents.on("change", onWalletsChanged);
|
|
436
|
+
cleanups.push(unsubscribe);
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
return () => {
|
|
440
|
+
cleanups.forEach(remove => remove());
|
|
441
|
+
};
|
|
442
|
+
}
|
|
430
443
|
/**
|
|
431
444
|
* @internal
|
|
432
445
|
* Schedules a session expiration and warning timeout for the given session key.
|
|
@@ -469,7 +482,7 @@ const ClientProvider = ({
|
|
|
469
482
|
callbacks?.beforeSessionExpiry?.({
|
|
470
483
|
sessionKey
|
|
471
484
|
});
|
|
472
|
-
if (autoRefreshSession) {
|
|
485
|
+
if (masterConfig?.auth?.autoRefreshSession) {
|
|
473
486
|
await refreshSession({
|
|
474
487
|
expirationSeconds: session.expirationSeconds,
|
|
475
488
|
sessionKey
|
|
@@ -484,6 +497,17 @@ const ClientProvider = ({
|
|
|
484
497
|
callbacks?.onSessionExpired?.({
|
|
485
498
|
sessionKey
|
|
486
499
|
});
|
|
500
|
+
if ((await getActiveSessionKey()) === sessionKey) {
|
|
501
|
+
setSession(undefined);
|
|
502
|
+
}
|
|
503
|
+
setAllSessions(prevSessions => {
|
|
504
|
+
if (!prevSessions) return prevSessions;
|
|
505
|
+
const newSessions = {
|
|
506
|
+
...prevSessions
|
|
507
|
+
};
|
|
508
|
+
delete newSessions[sessionKey];
|
|
509
|
+
return newSessions;
|
|
510
|
+
});
|
|
487
511
|
await clearSession({
|
|
488
512
|
sessionKey
|
|
489
513
|
});
|
|
@@ -589,23 +613,23 @@ const ClientProvider = ({
|
|
|
589
613
|
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to initialize sessions`, sdkTypes.TurnkeyErrorCodes.HANDLE_POST_LOGOUT_ERROR, error));
|
|
590
614
|
}
|
|
591
615
|
};
|
|
592
|
-
|
|
616
|
+
const createPasskey = react.useCallback(async params => {
|
|
593
617
|
if (!client) {
|
|
594
618
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
595
619
|
}
|
|
596
620
|
return utils.withTurnkeyErrorHandling(() => client.createPasskey({
|
|
597
621
|
...params
|
|
598
622
|
}), callbacks, "Failed to create passkey");
|
|
599
|
-
}
|
|
600
|
-
|
|
623
|
+
}, [client, callbacks]);
|
|
624
|
+
const logout = react.useCallback(async params => {
|
|
601
625
|
if (!client) {
|
|
602
626
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
603
627
|
}
|
|
604
|
-
utils.withTurnkeyErrorHandling(() => client.logout(params), callbacks, "Failed to logout");
|
|
628
|
+
await utils.withTurnkeyErrorHandling(() => client.logout(params), callbacks, "Failed to logout");
|
|
605
629
|
handlePostLogout();
|
|
606
630
|
return;
|
|
607
|
-
}
|
|
608
|
-
|
|
631
|
+
}, [client, callbacks]);
|
|
632
|
+
const loginWithPasskey = react.useCallback(async params => {
|
|
609
633
|
if (!client) {
|
|
610
634
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
611
635
|
}
|
|
@@ -618,8 +642,8 @@ const ClientProvider = ({
|
|
|
618
642
|
await handlePostAuth();
|
|
619
643
|
}
|
|
620
644
|
return res;
|
|
621
|
-
}
|
|
622
|
-
|
|
645
|
+
}, [client, callbacks]);
|
|
646
|
+
const signUpWithPasskey = react.useCallback(async params => {
|
|
623
647
|
if (!client) {
|
|
624
648
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
625
649
|
}
|
|
@@ -653,88 +677,54 @@ const ClientProvider = ({
|
|
|
653
677
|
await handlePostAuth();
|
|
654
678
|
}
|
|
655
679
|
return res;
|
|
656
|
-
}
|
|
657
|
-
|
|
680
|
+
}, [client, callbacks]);
|
|
681
|
+
const getWalletProviders = react.useCallback(async chain => {
|
|
658
682
|
if (!client) {
|
|
659
683
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
660
684
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
685
|
+
const newProviders = await client.getWalletProviders(chain);
|
|
686
|
+
// we update state with the latest providers
|
|
687
|
+
// we keep this state so that initializeWalletProviderListeners() re-runs
|
|
688
|
+
// whenever the list of connected providers changes
|
|
689
|
+
// this ensures we attach disconnect listeners for each connected provider
|
|
690
|
+
setWalletProviders(newProviders);
|
|
691
|
+
return newProviders;
|
|
692
|
+
}, [client, callbacks]);
|
|
693
|
+
const connectWalletAccount = react.useCallback(async walletProvider => {
|
|
664
694
|
if (!client) {
|
|
665
695
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
666
696
|
}
|
|
667
697
|
await client.connectWalletAccount(walletProvider);
|
|
698
|
+
// this will update our walletProvider state
|
|
668
699
|
await refreshWallets();
|
|
669
|
-
}
|
|
670
|
-
|
|
700
|
+
}, [client, callbacks]);
|
|
701
|
+
const disconnectWalletAccount = react.useCallback(async walletProvider => {
|
|
671
702
|
if (!client) {
|
|
672
703
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
673
704
|
}
|
|
674
705
|
await client.disconnectWalletAccount(walletProvider);
|
|
675
|
-
// we only refresh the wallets if
|
|
676
|
-
//
|
|
677
|
-
// actually being logged in
|
|
678
|
-
|
|
706
|
+
// we only refresh the wallets if:
|
|
707
|
+
// 1. there is an active session. This is needed because for WalletConnect
|
|
708
|
+
// you can unlink a wallet before actually being logged in
|
|
709
|
+
//
|
|
710
|
+
// 2. it was a WalletConnect provider that we just disconnected. Since
|
|
711
|
+
// native providers emit a disconnect event which will already refresh
|
|
712
|
+
// the wallets. This event is triggered in `initializeWalletProviderListeners()`
|
|
713
|
+
if (session && walletProvider.interfaceType === core.WalletInterfaceType.WalletConnect) {
|
|
714
|
+
// this will update our walletProvider state
|
|
679
715
|
await refreshWallets();
|
|
680
716
|
}
|
|
681
|
-
}
|
|
682
|
-
|
|
717
|
+
}, [client, callbacks]);
|
|
718
|
+
const switchWalletAccountChain = react.useCallback(async params => {
|
|
683
719
|
if (!client) {
|
|
684
720
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
685
721
|
}
|
|
686
|
-
await client.
|
|
687
|
-
|
|
688
|
-
|
|
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);
|
|
722
|
+
await client.switchWalletAccountChain({
|
|
723
|
+
...params,
|
|
724
|
+
walletProviders
|
|
732
725
|
});
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
async function loginWithWallet(params) {
|
|
726
|
+
}, [client, callbacks]);
|
|
727
|
+
const loginWithWallet = react.useCallback(async params => {
|
|
738
728
|
if (!client) {
|
|
739
729
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
740
730
|
}
|
|
@@ -747,8 +737,8 @@ const ClientProvider = ({
|
|
|
747
737
|
await handlePostAuth();
|
|
748
738
|
}
|
|
749
739
|
return res;
|
|
750
|
-
}
|
|
751
|
-
|
|
740
|
+
}, [client, callbacks]);
|
|
741
|
+
const signUpWithWallet = react.useCallback(async params => {
|
|
752
742
|
if (!client) {
|
|
753
743
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
754
744
|
}
|
|
@@ -772,8 +762,8 @@ const ClientProvider = ({
|
|
|
772
762
|
await handlePostAuth();
|
|
773
763
|
}
|
|
774
764
|
return res;
|
|
775
|
-
}
|
|
776
|
-
|
|
765
|
+
}, [client, callbacks, masterConfig]);
|
|
766
|
+
const loginOrSignupWithWallet = react.useCallback(async params => {
|
|
777
767
|
if (!client) {
|
|
778
768
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
779
769
|
}
|
|
@@ -797,20 +787,20 @@ const ClientProvider = ({
|
|
|
797
787
|
await handlePostAuth();
|
|
798
788
|
}
|
|
799
789
|
return res;
|
|
800
|
-
}
|
|
801
|
-
|
|
790
|
+
}, [client, callbacks, masterConfig]);
|
|
791
|
+
const initOtp = react.useCallback(async params => {
|
|
802
792
|
if (!client) {
|
|
803
793
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
804
794
|
}
|
|
805
795
|
return utils.withTurnkeyErrorHandling(() => client.initOtp(params), callbacks, "Failed to initialize OTP");
|
|
806
|
-
}
|
|
807
|
-
|
|
796
|
+
}, [client, callbacks]);
|
|
797
|
+
const verifyOtp = react.useCallback(async params => {
|
|
808
798
|
if (!client) {
|
|
809
799
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
810
800
|
}
|
|
811
801
|
return utils.withTurnkeyErrorHandling(() => client.verifyOtp(params), callbacks, "Failed to verify OTP");
|
|
812
|
-
}
|
|
813
|
-
|
|
802
|
+
}, [client, callbacks]);
|
|
803
|
+
const loginWithOtp = react.useCallback(async params => {
|
|
814
804
|
if (!client) {
|
|
815
805
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
816
806
|
}
|
|
@@ -819,8 +809,8 @@ const ClientProvider = ({
|
|
|
819
809
|
await handlePostAuth();
|
|
820
810
|
}
|
|
821
811
|
return res;
|
|
822
|
-
}
|
|
823
|
-
|
|
812
|
+
}, [client, callbacks]);
|
|
813
|
+
const signUpWithOtp = react.useCallback(async params => {
|
|
824
814
|
if (!client) {
|
|
825
815
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
826
816
|
}
|
|
@@ -847,8 +837,8 @@ const ClientProvider = ({
|
|
|
847
837
|
await handlePostAuth();
|
|
848
838
|
}
|
|
849
839
|
return res;
|
|
850
|
-
}
|
|
851
|
-
|
|
840
|
+
}, [client, callbacks, masterConfig]);
|
|
841
|
+
const completeOtp = react.useCallback(async params => {
|
|
852
842
|
if (!client) {
|
|
853
843
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
854
844
|
}
|
|
@@ -875,8 +865,8 @@ const ClientProvider = ({
|
|
|
875
865
|
await handlePostAuth();
|
|
876
866
|
}
|
|
877
867
|
return res;
|
|
878
|
-
}
|
|
879
|
-
|
|
868
|
+
}, [client, callbacks, masterConfig]);
|
|
869
|
+
const completeOauth = react.useCallback(async params => {
|
|
880
870
|
if (!client) {
|
|
881
871
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
882
872
|
}
|
|
@@ -896,8 +886,8 @@ const ClientProvider = ({
|
|
|
896
886
|
await handlePostAuth();
|
|
897
887
|
}
|
|
898
888
|
return res;
|
|
899
|
-
}
|
|
900
|
-
|
|
889
|
+
}, [client, callbacks, masterConfig]);
|
|
890
|
+
const loginWithOauth = react.useCallback(async params => {
|
|
901
891
|
if (!client) {
|
|
902
892
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
903
893
|
}
|
|
@@ -906,8 +896,8 @@ const ClientProvider = ({
|
|
|
906
896
|
await handlePostAuth();
|
|
907
897
|
}
|
|
908
898
|
return res;
|
|
909
|
-
}
|
|
910
|
-
|
|
899
|
+
}, [client, callbacks]);
|
|
900
|
+
const signUpWithOauth = react.useCallback(async params => {
|
|
911
901
|
if (!client) {
|
|
912
902
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
913
903
|
}
|
|
@@ -927,24 +917,24 @@ const ClientProvider = ({
|
|
|
927
917
|
await handlePostAuth();
|
|
928
918
|
}
|
|
929
919
|
return res;
|
|
930
|
-
}
|
|
931
|
-
|
|
920
|
+
}, [client, callbacks, masterConfig]);
|
|
921
|
+
const fetchWallets = react.useCallback(async params => {
|
|
932
922
|
if (!client) {
|
|
933
923
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
934
924
|
}
|
|
935
925
|
return utils.withTurnkeyErrorHandling(() => client.fetchWallets(params), callbacks, "Failed to fetch wallets");
|
|
936
|
-
}
|
|
937
|
-
|
|
926
|
+
}, [client, callbacks]);
|
|
927
|
+
const fetchWalletAccounts = react.useCallback(async params => {
|
|
938
928
|
if (!client) {
|
|
939
929
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
940
930
|
}
|
|
941
931
|
return utils.withTurnkeyErrorHandling(() => client.fetchWalletAccounts(params), callbacks, "Failed to fetch wallet accounts");
|
|
942
|
-
}
|
|
943
|
-
|
|
932
|
+
}, [client, callbacks]);
|
|
933
|
+
const signMessage = react.useCallback(async params => {
|
|
944
934
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
945
935
|
return utils.withTurnkeyErrorHandling(() => client.signMessage(params), callbacks, "Failed to sign message");
|
|
946
|
-
}
|
|
947
|
-
|
|
936
|
+
}, [client, callbacks]);
|
|
937
|
+
const handleSignMessage = react.useCallback(async params => {
|
|
948
938
|
const {
|
|
949
939
|
successPageDuration = 2000
|
|
950
940
|
} = params;
|
|
@@ -976,128 +966,146 @@ const ClientProvider = ({
|
|
|
976
966
|
})
|
|
977
967
|
});
|
|
978
968
|
});
|
|
979
|
-
}
|
|
980
|
-
|
|
969
|
+
}, [client, callbacks]);
|
|
970
|
+
const signTransaction = react.useCallback(async params => {
|
|
981
971
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
982
972
|
return utils.withTurnkeyErrorHandling(() => client.signTransaction(params), callbacks, "Failed to sign transaction");
|
|
983
|
-
}
|
|
984
|
-
|
|
973
|
+
}, [client, callbacks]);
|
|
974
|
+
const signAndSendTransaction = react.useCallback(async params => {
|
|
985
975
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
986
976
|
return utils.withTurnkeyErrorHandling(() => client.signAndSendTransaction(params), callbacks, "Failed to sign transaction");
|
|
987
|
-
}
|
|
988
|
-
|
|
977
|
+
}, [client, callbacks]);
|
|
978
|
+
const fetchUser = react.useCallback(async params => {
|
|
989
979
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
990
980
|
return utils.withTurnkeyErrorHandling(() => client.fetchUser(params), callbacks, "Failed to fetch user");
|
|
991
|
-
}
|
|
992
|
-
|
|
981
|
+
}, [client, callbacks]);
|
|
982
|
+
const updateUserEmail = react.useCallback(async params => {
|
|
993
983
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
994
984
|
const res = await utils.withTurnkeyErrorHandling(() => client.updateUserEmail(params), callbacks, "Failed to update user email");
|
|
995
985
|
if (res) await refreshUser({
|
|
996
986
|
stampWith: params?.stampWith
|
|
997
987
|
});
|
|
998
988
|
return res;
|
|
999
|
-
}
|
|
1000
|
-
|
|
989
|
+
}, [client, callbacks]);
|
|
990
|
+
const removeUserEmail = react.useCallback(async params => {
|
|
1001
991
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1002
992
|
const res = await utils.withTurnkeyErrorHandling(() => client.removeUserEmail(params), callbacks, "Failed to remove user email");
|
|
1003
993
|
if (res) await refreshUser({
|
|
1004
994
|
stampWith: params?.stampWith
|
|
1005
995
|
});
|
|
1006
996
|
return res;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
997
|
+
}, [client, callbacks]);
|
|
998
|
+
const updateUserPhoneNumber = react.useCallback(async params => {
|
|
1009
999
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1010
1000
|
const res = await utils.withTurnkeyErrorHandling(() => client.updateUserPhoneNumber(params), callbacks, "Failed to update user phone number");
|
|
1011
1001
|
if (res) await refreshUser({
|
|
1012
1002
|
stampWith: params?.stampWith
|
|
1013
1003
|
});
|
|
1014
1004
|
return res;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1005
|
+
}, [client, callbacks]);
|
|
1006
|
+
const removeUserPhoneNumber = react.useCallback(async params => {
|
|
1017
1007
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1018
1008
|
const res = await utils.withTurnkeyErrorHandling(() => client.removeUserPhoneNumber(params), callbacks, "Failed to remove user phone number");
|
|
1019
1009
|
if (res) await refreshUser({
|
|
1020
1010
|
stampWith: params?.stampWith
|
|
1021
1011
|
});
|
|
1022
1012
|
return res;
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1013
|
+
}, [client, callbacks]);
|
|
1014
|
+
const updateUserName = react.useCallback(async params => {
|
|
1025
1015
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1026
1016
|
const res = await utils.withTurnkeyErrorHandling(() => client.updateUserName(params), callbacks, "Failed to update user name");
|
|
1027
1017
|
if (res) await refreshUser({
|
|
1028
1018
|
stampWith: params?.stampWith
|
|
1029
1019
|
});
|
|
1030
1020
|
return res;
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1021
|
+
}, [client, callbacks]);
|
|
1022
|
+
const addOauthProvider = react.useCallback(async params => {
|
|
1033
1023
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1034
1024
|
const res = await utils.withTurnkeyErrorHandling(() => client.addOauthProvider(params), callbacks, "Failed to add OAuth provider");
|
|
1035
1025
|
if (res) await refreshUser({
|
|
1036
1026
|
stampWith: params?.stampWith
|
|
1037
1027
|
});
|
|
1038
1028
|
return res;
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1029
|
+
}, [client, callbacks]);
|
|
1030
|
+
const removeOauthProviders = react.useCallback(async params => {
|
|
1041
1031
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1042
1032
|
const res = await utils.withTurnkeyErrorHandling(() => client.removeOauthProviders(params), callbacks, "Failed to remove OAuth providers");
|
|
1043
1033
|
if (res) await refreshUser({
|
|
1044
1034
|
stampWith: params?.stampWith
|
|
1045
1035
|
});
|
|
1046
1036
|
return res;
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1037
|
+
}, [client, callbacks]);
|
|
1038
|
+
const addPasskey = react.useCallback(async params => {
|
|
1049
1039
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1050
1040
|
const res = await utils.withTurnkeyErrorHandling(() => client.addPasskey(params), callbacks, "Failed to add passkey");
|
|
1051
1041
|
if (res) await refreshUser({
|
|
1052
1042
|
stampWith: params?.stampWith
|
|
1053
1043
|
});
|
|
1054
1044
|
return res;
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1045
|
+
}, [client, callbacks]);
|
|
1046
|
+
const removePasskeys = react.useCallback(async params => {
|
|
1057
1047
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1058
1048
|
const res = await utils.withTurnkeyErrorHandling(() => client.removePasskeys(params), callbacks, "Failed to remove passkeys");
|
|
1059
1049
|
if (res) await refreshUser({
|
|
1060
1050
|
stampWith: params?.stampWith
|
|
1061
1051
|
});
|
|
1062
1052
|
return res;
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1053
|
+
}, [client, callbacks]);
|
|
1054
|
+
const createWallet = react.useCallback(async params => {
|
|
1065
1055
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1066
1056
|
const res = await utils.withTurnkeyErrorHandling(() => client.createWallet(params), callbacks, "Failed to create wallet");
|
|
1067
1057
|
if (res) await refreshWallets({
|
|
1068
1058
|
stampWith: params?.stampWith
|
|
1069
1059
|
});
|
|
1070
1060
|
return res;
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1061
|
+
}, [client, callbacks]);
|
|
1062
|
+
const createWalletAccounts = react.useCallback(async params => {
|
|
1073
1063
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1074
1064
|
const res = await utils.withTurnkeyErrorHandling(() => client.createWalletAccounts(params), callbacks, "Failed to create wallet accounts");
|
|
1075
1065
|
if (res) await refreshWallets({
|
|
1076
1066
|
stampWith: params?.stampWith
|
|
1077
1067
|
});
|
|
1078
1068
|
return res;
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1069
|
+
}, [client, callbacks]);
|
|
1070
|
+
const exportWallet = react.useCallback(async params => {
|
|
1081
1071
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1082
1072
|
const res = await utils.withTurnkeyErrorHandling(() => client.exportWallet(params), callbacks, "Failed to export wallet");
|
|
1083
1073
|
if (res) await refreshWallets({
|
|
1084
1074
|
stampWith: params?.stampWith
|
|
1085
1075
|
});
|
|
1086
1076
|
return res;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1077
|
+
}, [client, callbacks]);
|
|
1078
|
+
const exportPrivateKey = react.useCallback(async params => {
|
|
1079
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1080
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.exportPrivateKey(params), callbacks, "Failed to export private key");
|
|
1081
|
+
return res;
|
|
1082
|
+
}, [client, callbacks]);
|
|
1083
|
+
const exportWalletAccount = react.useCallback(async params => {
|
|
1084
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1085
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.exportWalletAccount(params), callbacks, "Failed to export wallet accounts");
|
|
1086
|
+
if (res) await refreshWallets({
|
|
1087
|
+
stampWith: params?.stampWith
|
|
1088
|
+
});
|
|
1089
|
+
return res;
|
|
1090
|
+
}, [client, callbacks]);
|
|
1091
|
+
const importWallet = react.useCallback(async params => {
|
|
1089
1092
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1090
1093
|
const res = await utils.withTurnkeyErrorHandling(() => client.importWallet(params), callbacks, "Failed to import wallet");
|
|
1091
1094
|
if (res) await refreshWallets({
|
|
1092
1095
|
stampWith: params?.stampWith
|
|
1093
1096
|
});
|
|
1094
1097
|
return res;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1098
|
+
}, [client, callbacks]);
|
|
1099
|
+
const importPrivateKey = react.useCallback(async params => {
|
|
1100
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1101
|
+
const res = await utils.withTurnkeyErrorHandling(() => client.importPrivateKey(params), callbacks, "Failed to import private key");
|
|
1102
|
+
return res;
|
|
1103
|
+
}, [client, callbacks]);
|
|
1104
|
+
const deleteSubOrganization = react.useCallback(async params => {
|
|
1097
1105
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1098
1106
|
return utils.withTurnkeyErrorHandling(() => client.deleteSubOrganization(params), callbacks, "Failed to delete sub-organization");
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1107
|
+
}, [client, callbacks]);
|
|
1108
|
+
const storeSession = react.useCallback(async params => {
|
|
1101
1109
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1102
1110
|
await utils.withTurnkeyErrorHandling(() => client.storeSession(params), callbacks, "Failed to store session");
|
|
1103
1111
|
const sessionKey = await getActiveSessionKey();
|
|
@@ -1114,8 +1122,8 @@ const ClientProvider = ({
|
|
|
1114
1122
|
setSession(session);
|
|
1115
1123
|
setAllSessions(allSessions);
|
|
1116
1124
|
return;
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1125
|
+
}, [client, callbacks]);
|
|
1126
|
+
const clearSession = react.useCallback(async params => {
|
|
1119
1127
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1120
1128
|
await utils.withTurnkeyErrorHandling(() => client.clearSession(params), callbacks, "Failed to clear session");
|
|
1121
1129
|
const session = await getSession();
|
|
@@ -1123,14 +1131,14 @@ const ClientProvider = ({
|
|
|
1123
1131
|
setSession(session);
|
|
1124
1132
|
setAllSessions(allSessions);
|
|
1125
1133
|
return;
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1134
|
+
}, [client, callbacks]);
|
|
1135
|
+
const clearAllSessions = react.useCallback(async () => {
|
|
1128
1136
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1129
1137
|
setSession(undefined);
|
|
1130
1138
|
setAllSessions(undefined);
|
|
1131
1139
|
return await utils.withTurnkeyErrorHandling(() => client.clearAllSessions(), callbacks, "Failed to clear all sessions");
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1140
|
+
}, [client, callbacks]);
|
|
1141
|
+
const refreshSession = react.useCallback(async params => {
|
|
1134
1142
|
if (!client) {
|
|
1135
1143
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1136
1144
|
}
|
|
@@ -1158,16 +1166,16 @@ const ClientProvider = ({
|
|
|
1158
1166
|
setSession(session);
|
|
1159
1167
|
setAllSessions(allSessions);
|
|
1160
1168
|
return res;
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1169
|
+
}, [client, callbacks]);
|
|
1170
|
+
const getSession = react.useCallback(async params => {
|
|
1163
1171
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1164
1172
|
return utils.withTurnkeyErrorHandling(() => client.getSession(params), callbacks, "Failed to get session");
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1173
|
+
}, [client, callbacks]);
|
|
1174
|
+
const getAllSessions = react.useCallback(async () => {
|
|
1167
1175
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1168
1176
|
return utils.withTurnkeyErrorHandling(() => client.getAllSessions(), callbacks, "Failed to get all sessions");
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1177
|
+
}, [client, callbacks]);
|
|
1178
|
+
const setActiveSession = react.useCallback(async params => {
|
|
1171
1179
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1172
1180
|
const session = await utils.withTurnkeyErrorHandling(() => client.getSession({
|
|
1173
1181
|
sessionKey: params.sessionKey
|
|
@@ -1178,24 +1186,24 @@ const ClientProvider = ({
|
|
|
1178
1186
|
await utils.withTurnkeyErrorHandling(() => client.setActiveSession(params), callbacks, "Failed to set active session");
|
|
1179
1187
|
setSession(session);
|
|
1180
1188
|
return;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1189
|
+
}, [client, callbacks]);
|
|
1190
|
+
const getActiveSessionKey = react.useCallback(async () => {
|
|
1183
1191
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1184
1192
|
return utils.withTurnkeyErrorHandling(() => client.getActiveSessionKey(), callbacks, "Failed to get active session key");
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1193
|
+
}, [client, callbacks]);
|
|
1194
|
+
const clearUnusedKeyPairs = react.useCallback(async () => {
|
|
1187
1195
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1188
1196
|
return utils.withTurnkeyErrorHandling(() => client.clearUnusedKeyPairs(), callbacks, "Failed to clear unused key pairs");
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1197
|
+
}, [client, callbacks]);
|
|
1198
|
+
const createApiKeyPair = react.useCallback(async params => {
|
|
1191
1199
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1192
1200
|
return utils.withTurnkeyErrorHandling(() => client.createApiKeyPair(params), callbacks, "Failed to create API key pair");
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1201
|
+
}, [client, callbacks]);
|
|
1202
|
+
const getProxyAuthConfig = react.useCallback(async () => {
|
|
1195
1203
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1196
1204
|
return utils.withTurnkeyErrorHandling(() => client.getProxyAuthConfig(), callbacks, "Failed to get proxy auth config");
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1205
|
+
}, [client, callbacks]);
|
|
1206
|
+
const refreshUser = react.useCallback(async params => {
|
|
1199
1207
|
const {
|
|
1200
1208
|
stampWith
|
|
1201
1209
|
} = params || {};
|
|
@@ -1206,20 +1214,22 @@ const ClientProvider = ({
|
|
|
1206
1214
|
if (user) {
|
|
1207
1215
|
setUser(user);
|
|
1208
1216
|
}
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1217
|
+
}, [client, callbacks]);
|
|
1218
|
+
const refreshWallets = react.useCallback(async params => {
|
|
1211
1219
|
const {
|
|
1212
1220
|
stampWith
|
|
1213
1221
|
} = params || {};
|
|
1214
1222
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1223
|
+
const walletProviders = await utils.withTurnkeyErrorHandling(() => getWalletProviders(), callbacks, "Failed to refresh wallets");
|
|
1215
1224
|
const wallets = await utils.withTurnkeyErrorHandling(() => fetchWallets({
|
|
1216
|
-
stampWith
|
|
1225
|
+
stampWith,
|
|
1226
|
+
walletProviders
|
|
1217
1227
|
}), callbacks, "Failed to refresh wallets");
|
|
1218
1228
|
if (wallets) {
|
|
1219
1229
|
setWallets(wallets);
|
|
1220
1230
|
}
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1231
|
+
}, [client, callbacks, getWalletProviders, fetchWallets]);
|
|
1232
|
+
const handleGoogleOauth = react.useCallback(async params => {
|
|
1223
1233
|
const {
|
|
1224
1234
|
clientId = masterConfig?.auth?.oauthConfig?.googleClientId,
|
|
1225
1235
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
@@ -1335,8 +1345,8 @@ const ClientProvider = ({
|
|
|
1335
1345
|
} catch (error) {
|
|
1336
1346
|
throw error;
|
|
1337
1347
|
}
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1348
|
+
}, [client, callbacks]);
|
|
1349
|
+
const handleAppleOauth = react.useCallback(async params => {
|
|
1340
1350
|
const {
|
|
1341
1351
|
clientId = masterConfig?.auth?.oauthConfig?.appleClientId,
|
|
1342
1352
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
@@ -1448,8 +1458,8 @@ const ClientProvider = ({
|
|
|
1448
1458
|
} catch (error) {
|
|
1449
1459
|
throw error;
|
|
1450
1460
|
}
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1461
|
+
}, [client, callbacks]);
|
|
1462
|
+
const handleFacebookOauth = react.useCallback(async params => {
|
|
1453
1463
|
const {
|
|
1454
1464
|
clientId = masterConfig?.auth?.oauthConfig?.facebookClientId,
|
|
1455
1465
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
@@ -1580,25 +1590,24 @@ const ClientProvider = ({
|
|
|
1580
1590
|
} catch (error) {
|
|
1581
1591
|
throw error;
|
|
1582
1592
|
}
|
|
1583
|
-
}
|
|
1584
|
-
const handleLogin = async () => {
|
|
1593
|
+
}, [client, callbacks]);
|
|
1594
|
+
const handleLogin = react.useCallback(async () => {
|
|
1585
1595
|
pushPage({
|
|
1586
1596
|
key: "Log in or sign up",
|
|
1587
1597
|
content: jsxRuntime.jsx(index.AuthComponent, {})
|
|
1588
1598
|
});
|
|
1589
|
-
};
|
|
1590
|
-
const
|
|
1599
|
+
}, [pushPage]);
|
|
1600
|
+
const handleExportWallet = react.useCallback(async params => {
|
|
1591
1601
|
const {
|
|
1592
1602
|
walletId,
|
|
1593
|
-
exportType,
|
|
1594
1603
|
targetPublicKey,
|
|
1595
1604
|
stampWith
|
|
1596
1605
|
} = params;
|
|
1597
1606
|
pushPage({
|
|
1598
1607
|
key: "Export Wallet",
|
|
1599
1608
|
content: jsxRuntime.jsx(Export.ExportComponent, {
|
|
1600
|
-
|
|
1601
|
-
exportType:
|
|
1609
|
+
target: walletId,
|
|
1610
|
+
exportType: base.ExportType.Wallet,
|
|
1602
1611
|
...(targetPublicKey !== undefined ? {
|
|
1603
1612
|
targetPublicKey
|
|
1604
1613
|
} : {}),
|
|
@@ -1607,8 +1616,48 @@ const ClientProvider = ({
|
|
|
1607
1616
|
} : {})
|
|
1608
1617
|
})
|
|
1609
1618
|
});
|
|
1610
|
-
};
|
|
1611
|
-
const
|
|
1619
|
+
}, [pushPage]);
|
|
1620
|
+
const handleExportPrivateKey = react.useCallback(async params => {
|
|
1621
|
+
const {
|
|
1622
|
+
privateKeyId,
|
|
1623
|
+
targetPublicKey,
|
|
1624
|
+
stampWith
|
|
1625
|
+
} = params;
|
|
1626
|
+
pushPage({
|
|
1627
|
+
key: "Export Private Key",
|
|
1628
|
+
content: jsxRuntime.jsx(Export.ExportComponent, {
|
|
1629
|
+
target: privateKeyId,
|
|
1630
|
+
exportType: base.ExportType.PrivateKey,
|
|
1631
|
+
...(targetPublicKey !== undefined ? {
|
|
1632
|
+
targetPublicKey
|
|
1633
|
+
} : {}),
|
|
1634
|
+
...(stampWith !== undefined ? {
|
|
1635
|
+
stampWith
|
|
1636
|
+
} : {})
|
|
1637
|
+
})
|
|
1638
|
+
});
|
|
1639
|
+
}, [pushPage]);
|
|
1640
|
+
const handleExportWalletAccount = react.useCallback(async params => {
|
|
1641
|
+
const {
|
|
1642
|
+
address,
|
|
1643
|
+
targetPublicKey,
|
|
1644
|
+
stampWith
|
|
1645
|
+
} = params;
|
|
1646
|
+
pushPage({
|
|
1647
|
+
key: "Export Wallet Account",
|
|
1648
|
+
content: jsxRuntime.jsx(Export.ExportComponent, {
|
|
1649
|
+
target: address,
|
|
1650
|
+
exportType: base.ExportType.WalletAccount,
|
|
1651
|
+
...(targetPublicKey !== undefined ? {
|
|
1652
|
+
targetPublicKey
|
|
1653
|
+
} : {}),
|
|
1654
|
+
...(stampWith !== undefined ? {
|
|
1655
|
+
stampWith
|
|
1656
|
+
} : {})
|
|
1657
|
+
})
|
|
1658
|
+
});
|
|
1659
|
+
}, [pushPage]);
|
|
1660
|
+
const handleImportWallet = react.useCallback(async params => {
|
|
1612
1661
|
const {
|
|
1613
1662
|
defaultWalletAccounts,
|
|
1614
1663
|
successPageDuration = 2000,
|
|
@@ -1639,8 +1688,8 @@ const ClientProvider = ({
|
|
|
1639
1688
|
}
|
|
1640
1689
|
throw new sdkTypes.TurnkeyError("Failed to import wallet.", sdkTypes.TurnkeyErrorCodes.IMPORT_WALLET_ERROR, error);
|
|
1641
1690
|
}
|
|
1642
|
-
};
|
|
1643
|
-
const handleUpdateUserName = async params => {
|
|
1691
|
+
}, [pushPage]);
|
|
1692
|
+
const handleUpdateUserName = react.useCallback(async params => {
|
|
1644
1693
|
const {
|
|
1645
1694
|
successPageDuration = 2000,
|
|
1646
1695
|
subTitle,
|
|
@@ -1705,8 +1754,8 @@ const ClientProvider = ({
|
|
|
1705
1754
|
}
|
|
1706
1755
|
throw new sdkTypes.TurnkeyError("Failed to update user name.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_NAME_ERROR, error);
|
|
1707
1756
|
}
|
|
1708
|
-
};
|
|
1709
|
-
const handleUpdateUserPhoneNumber = async params => {
|
|
1757
|
+
}, [pushPage]);
|
|
1758
|
+
const handleUpdateUserPhoneNumber = react.useCallback(async params => {
|
|
1710
1759
|
const {
|
|
1711
1760
|
successPageDuration = 2000,
|
|
1712
1761
|
subTitle,
|
|
@@ -1809,8 +1858,8 @@ const ClientProvider = ({
|
|
|
1809
1858
|
}
|
|
1810
1859
|
throw new sdkTypes.TurnkeyError("Failed to initialize OTP for sms verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
|
|
1811
1860
|
}
|
|
1812
|
-
};
|
|
1813
|
-
const handleUpdateUserEmail = async params => {
|
|
1861
|
+
}, [pushPage]);
|
|
1862
|
+
const handleUpdateUserEmail = react.useCallback(async params => {
|
|
1814
1863
|
const {
|
|
1815
1864
|
successPageDuration = 2000,
|
|
1816
1865
|
subTitle,
|
|
@@ -1906,8 +1955,8 @@ const ClientProvider = ({
|
|
|
1906
1955
|
}
|
|
1907
1956
|
throw new sdkTypes.TurnkeyError("Failed to initialize OTP for email verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
|
|
1908
1957
|
}
|
|
1909
|
-
};
|
|
1910
|
-
const handleAddEmail = async params => {
|
|
1958
|
+
}, [pushPage]);
|
|
1959
|
+
const handleAddEmail = react.useCallback(async params => {
|
|
1911
1960
|
const {
|
|
1912
1961
|
successPageDuration = 2000,
|
|
1913
1962
|
subTitle,
|
|
@@ -2003,8 +2052,8 @@ const ClientProvider = ({
|
|
|
2003
2052
|
}
|
|
2004
2053
|
throw new sdkTypes.TurnkeyError("Failed to initialize OTP for email verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
|
|
2005
2054
|
}
|
|
2006
|
-
};
|
|
2007
|
-
const handleAddPhoneNumber = async params => {
|
|
2055
|
+
}, [pushPage]);
|
|
2056
|
+
const handleAddPhoneNumber = react.useCallback(async params => {
|
|
2008
2057
|
const {
|
|
2009
2058
|
successPageDuration = 2000,
|
|
2010
2059
|
subTitle,
|
|
@@ -2111,8 +2160,8 @@ const ClientProvider = ({
|
|
|
2111
2160
|
}
|
|
2112
2161
|
throw new sdkTypes.TurnkeyError("Failed to initialize OTP for sms verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
|
|
2113
2162
|
}
|
|
2114
|
-
};
|
|
2115
|
-
const handleRemovePasskey = async params => {
|
|
2163
|
+
}, [pushPage]);
|
|
2164
|
+
const handleRemovePasskey = react.useCallback(async params => {
|
|
2116
2165
|
const {
|
|
2117
2166
|
authenticatorId,
|
|
2118
2167
|
successPageDuration = 2000,
|
|
@@ -2152,8 +2201,8 @@ const ClientProvider = ({
|
|
|
2152
2201
|
preventBack: true
|
|
2153
2202
|
});
|
|
2154
2203
|
}), callbacks, "Failed to remove passkey");
|
|
2155
|
-
};
|
|
2156
|
-
const handleAddPasskey = async params => {
|
|
2204
|
+
}, [pushPage]);
|
|
2205
|
+
const handleAddPasskey = react.useCallback(async params => {
|
|
2157
2206
|
const {
|
|
2158
2207
|
name,
|
|
2159
2208
|
displayName,
|
|
@@ -2197,8 +2246,8 @@ const ClientProvider = ({
|
|
|
2197
2246
|
}
|
|
2198
2247
|
throw new sdkTypes.TurnkeyError("Failed to add passkey in handler.", sdkTypes.TurnkeyErrorCodes.ADD_PASSKEY_ERROR, error);
|
|
2199
2248
|
}
|
|
2200
|
-
};
|
|
2201
|
-
const handleRemoveOauthProvider = async params => {
|
|
2249
|
+
}, [pushPage]);
|
|
2250
|
+
const handleRemoveOauthProvider = react.useCallback(async params => {
|
|
2202
2251
|
const {
|
|
2203
2252
|
providerId,
|
|
2204
2253
|
successPageDuration = 2000,
|
|
@@ -2241,8 +2290,8 @@ const ClientProvider = ({
|
|
|
2241
2290
|
}
|
|
2242
2291
|
throw new sdkTypes.TurnkeyError("Failed to remove OAuth provider in handler.", sdkTypes.TurnkeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR, error);
|
|
2243
2292
|
}
|
|
2244
|
-
};
|
|
2245
|
-
const handleAddOauthProvider = async params => {
|
|
2293
|
+
}, [pushPage]);
|
|
2294
|
+
const handleAddOauthProvider = react.useCallback(async params => {
|
|
2246
2295
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2247
2296
|
if (!session) {
|
|
2248
2297
|
throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
|
|
@@ -2300,8 +2349,8 @@ const ClientProvider = ({
|
|
|
2300
2349
|
throw new sdkTypes.TurnkeyError(`Unsupported OAuth provider: ${providerName}`, sdkTypes.TurnkeyErrorCodes.NOT_FOUND);
|
|
2301
2350
|
}
|
|
2302
2351
|
}
|
|
2303
|
-
};
|
|
2304
|
-
const handleLinkExternalWallet = async params => {
|
|
2352
|
+
}, [pushPage]);
|
|
2353
|
+
const handleLinkExternalWallet = react.useCallback(async params => {
|
|
2305
2354
|
const {
|
|
2306
2355
|
successPageDuration = 2000
|
|
2307
2356
|
} = params || {};
|
|
@@ -2320,8 +2369,8 @@ const ClientProvider = ({
|
|
|
2320
2369
|
successPageDuration: successPageDuration
|
|
2321
2370
|
})
|
|
2322
2371
|
});
|
|
2323
|
-
};
|
|
2324
|
-
const handleRemoveUserEmail = async params => {
|
|
2372
|
+
}, [pushPage]);
|
|
2373
|
+
const handleRemoveUserEmail = react.useCallback(async params => {
|
|
2325
2374
|
const {
|
|
2326
2375
|
successPageDuration = 2000,
|
|
2327
2376
|
stampWith,
|
|
@@ -2359,8 +2408,8 @@ const ClientProvider = ({
|
|
|
2359
2408
|
}
|
|
2360
2409
|
throw new sdkTypes.TurnkeyError("Failed to remove user email.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_EMAIL_ERROR, error);
|
|
2361
2410
|
}
|
|
2362
|
-
};
|
|
2363
|
-
const handleRemoveUserPhoneNumber = async params => {
|
|
2411
|
+
}, [pushPage]);
|
|
2412
|
+
const handleRemoveUserPhoneNumber = react.useCallback(async params => {
|
|
2364
2413
|
const {
|
|
2365
2414
|
successPageDuration = 2000,
|
|
2366
2415
|
stampWith,
|
|
@@ -2398,7 +2447,91 @@ const ClientProvider = ({
|
|
|
2398
2447
|
}
|
|
2399
2448
|
throw new sdkTypes.TurnkeyError("Failed to remove user phone number.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR, error);
|
|
2400
2449
|
}
|
|
2401
|
-
};
|
|
2450
|
+
}, [pushPage]);
|
|
2451
|
+
react.useEffect(() => {
|
|
2452
|
+
if (proxyAuthConfigRef.current) return;
|
|
2453
|
+
// Only fetch the proxy auth config once. Use that to build the master config.
|
|
2454
|
+
const fetchProxyAuthConfig = async () => {
|
|
2455
|
+
try {
|
|
2456
|
+
let proxyAuthConfig;
|
|
2457
|
+
if (config.authProxyConfigId) {
|
|
2458
|
+
// Only fetch the proxy auth config if we have an authProxyId. This is a way for devs to explicitly disable the proxy auth.
|
|
2459
|
+
proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId, config.authProxyUrl);
|
|
2460
|
+
proxyAuthConfigRef.current = proxyAuthConfig;
|
|
2461
|
+
}
|
|
2462
|
+
setMasterConfig(buildConfig(proxyAuthConfig));
|
|
2463
|
+
} catch {
|
|
2464
|
+
setClientState(base.ClientState.Error);
|
|
2465
|
+
}
|
|
2466
|
+
};
|
|
2467
|
+
fetchProxyAuthConfig();
|
|
2468
|
+
}, []);
|
|
2469
|
+
react.useEffect(() => {
|
|
2470
|
+
// Start the client initialization process once we have the master config.
|
|
2471
|
+
if (!masterConfig) return;
|
|
2472
|
+
initializeClient();
|
|
2473
|
+
}, [masterConfig]);
|
|
2474
|
+
react.useEffect(() => {
|
|
2475
|
+
// Handle changes to the passed in config prop -- update the master config
|
|
2476
|
+
// 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
|
|
2477
|
+
if (!proxyAuthConfigRef.current && config.authProxyConfigId) return;
|
|
2478
|
+
setMasterConfig(buildConfig(proxyAuthConfigRef.current ?? undefined));
|
|
2479
|
+
}, [config, proxyAuthConfigRef.current]);
|
|
2480
|
+
/**
|
|
2481
|
+
* @internal
|
|
2482
|
+
* We create `debouncedRefreshWallets()` so that multiple rapid wallet events
|
|
2483
|
+
* (for example, on Solana a single disconnect can emit several events we listen for)
|
|
2484
|
+
* only trigger `refreshWallets()` once.
|
|
2485
|
+
*
|
|
2486
|
+
* Defining the debounced function outside of the `useEffect` ensures all event
|
|
2487
|
+
* listeners in `initializeProviders` share the same instance, instead of creating
|
|
2488
|
+
* a new one on every render.
|
|
2489
|
+
*/
|
|
2490
|
+
const debouncedRefreshWallets = utils.useDebouncedCallback(refreshWallets, 100);
|
|
2491
|
+
react.useEffect(() => {
|
|
2492
|
+
if (!client) return;
|
|
2493
|
+
const handleRefreshWallets = async () => {
|
|
2494
|
+
// we only refresh the wallets if there is an active session
|
|
2495
|
+
// this is needed because a disconnect event can occur
|
|
2496
|
+
// while the user is unauthenticated
|
|
2497
|
+
if (session) {
|
|
2498
|
+
// this will update our walletProvider state
|
|
2499
|
+
await debouncedRefreshWallets();
|
|
2500
|
+
}
|
|
2501
|
+
};
|
|
2502
|
+
let cleanup = () => {};
|
|
2503
|
+
initializeWalletProviderListeners(walletProviders, handleRefreshWallets).then(fn => {
|
|
2504
|
+
cleanup = fn;
|
|
2505
|
+
}).catch(err => {
|
|
2506
|
+
console.error("Failed to init providers:", err);
|
|
2507
|
+
});
|
|
2508
|
+
return () => {
|
|
2509
|
+
cleanup();
|
|
2510
|
+
};
|
|
2511
|
+
}, [client, walletProviders]);
|
|
2512
|
+
react.useEffect(() => {
|
|
2513
|
+
// 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.
|
|
2514
|
+
// This will ensure that they are always in sync and remove the need to setAuthState manually in other places.
|
|
2515
|
+
if (session && utils.isValidSession(session)) {
|
|
2516
|
+
setAuthState(base.AuthState.Authenticated);
|
|
2517
|
+
} else {
|
|
2518
|
+
setAuthState(base.AuthState.Unauthenticated);
|
|
2519
|
+
}
|
|
2520
|
+
}, [session]);
|
|
2521
|
+
react.useEffect(() => {
|
|
2522
|
+
// This will handle any redirect based oAuth. It then initializes the session. This is the last step before client is considered "ready"
|
|
2523
|
+
if (!client || !masterConfig) return;
|
|
2524
|
+
completeRedirectOauth().finally(() => {
|
|
2525
|
+
clearSessionTimeouts();
|
|
2526
|
+
initializeSessions().finally(() => {
|
|
2527
|
+
// Set the client state to ready only after all initializations are done.
|
|
2528
|
+
setClientState(base.ClientState.Ready);
|
|
2529
|
+
});
|
|
2530
|
+
});
|
|
2531
|
+
return () => {
|
|
2532
|
+
clearSessionTimeouts();
|
|
2533
|
+
};
|
|
2534
|
+
}, [client]);
|
|
2402
2535
|
return jsxRuntime.jsx(Types.ClientContext.Provider, {
|
|
2403
2536
|
value: {
|
|
2404
2537
|
session,
|
|
@@ -2416,7 +2549,7 @@ const ClientProvider = ({
|
|
|
2416
2549
|
getWalletProviders,
|
|
2417
2550
|
connectWalletAccount,
|
|
2418
2551
|
disconnectWalletAccount,
|
|
2419
|
-
|
|
2552
|
+
switchWalletAccountChain,
|
|
2420
2553
|
loginWithWallet,
|
|
2421
2554
|
signUpWithWallet,
|
|
2422
2555
|
loginOrSignupWithWallet,
|
|
@@ -2448,7 +2581,10 @@ const ClientProvider = ({
|
|
|
2448
2581
|
createWallet,
|
|
2449
2582
|
createWalletAccounts,
|
|
2450
2583
|
exportWallet,
|
|
2584
|
+
exportPrivateKey,
|
|
2585
|
+
exportWalletAccount,
|
|
2451
2586
|
importWallet,
|
|
2587
|
+
importPrivateKey,
|
|
2452
2588
|
deleteSubOrganization,
|
|
2453
2589
|
storeSession,
|
|
2454
2590
|
clearSession,
|
|
@@ -2465,8 +2601,10 @@ const ClientProvider = ({
|
|
|
2465
2601
|
handleGoogleOauth,
|
|
2466
2602
|
handleAppleOauth,
|
|
2467
2603
|
handleFacebookOauth,
|
|
2468
|
-
|
|
2469
|
-
|
|
2604
|
+
handleExportWallet,
|
|
2605
|
+
handleExportPrivateKey,
|
|
2606
|
+
handleExportWalletAccount,
|
|
2607
|
+
handleImportWallet,
|
|
2470
2608
|
handleUpdateUserEmail,
|
|
2471
2609
|
handleUpdateUserPhoneNumber,
|
|
2472
2610
|
handleUpdateUserName,
|