@0xkey-io/react-wallet-kit 0.1.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 +116 -0
- package/dist/_virtual/_rollupPluginBabelHelpers.mjs +307 -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 +77 -0
- package/dist/components/auth/Email.js.map +1 -0
- package/dist/components/auth/Email.mjs +98 -0
- package/dist/components/auth/Email.mjs.map +1 -0
- package/dist/components/auth/OAuth.d.ts +13 -0
- package/dist/components/auth/OAuth.d.ts.map +1 -0
- package/dist/components/auth/OAuth.js +63 -0
- package/dist/components/auth/OAuth.js.map +1 -0
- package/dist/components/auth/OAuth.mjs +68 -0
- package/dist/components/auth/OAuth.mjs.map +1 -0
- package/dist/components/auth/OTP.d.ts +21 -0
- package/dist/components/auth/OTP.d.ts.map +1 -0
- package/dist/components/auth/OTP.js +218 -0
- package/dist/components/auth/OTP.js.map +1 -0
- package/dist/components/auth/OTP.mjs +301 -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 +34 -0
- package/dist/components/auth/Passkey.js.map +1 -0
- package/dist/components/auth/Passkey.mjs +30 -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 +92 -0
- package/dist/components/auth/Phone.mjs.map +1 -0
- package/dist/components/auth/Wallet.d.ts +34 -0
- package/dist/components/auth/Wallet.d.ts.map +1 -0
- package/dist/components/auth/Wallet.js +517 -0
- package/dist/components/auth/Wallet.js.map +1 -0
- package/dist/components/auth/Wallet.mjs +618 -0
- package/dist/components/auth/Wallet.mjs.map +1 -0
- package/dist/components/auth/index.d.ts +9 -0
- package/dist/components/auth/index.d.ts.map +1 -0
- package/dist/components/auth/index.js +457 -0
- package/dist/components/auth/index.js.map +1 -0
- package/dist/components/auth/index.mjs +672 -0
- package/dist/components/auth/index.mjs.map +1 -0
- package/dist/components/design/Buttons.d.ts +29 -0
- package/dist/components/design/Buttons.d.ts.map +1 -0
- package/dist/components/design/Buttons.js +87 -0
- package/dist/components/design/Buttons.js.map +1 -0
- package/dist/components/design/Buttons.mjs +79 -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 +135 -0
- package/dist/components/design/Inputs.js.map +1 -0
- package/dist/components/design/Inputs.mjs +133 -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 +24 -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 +42 -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 +13 -0
- package/dist/components/design/Svg.d.ts.map +1 -0
- package/dist/components/design/Svg.js +165 -0
- package/dist/components/design/Svg.js.map +1 -0
- package/dist/components/design/Svg.mjs +161 -0
- package/dist/components/design/Svg.mjs.map +1 -0
- package/dist/components/export/Export.d.ts +13 -0
- package/dist/components/export/Export.d.ts.map +1 -0
- package/dist/components/export/Export.js +169 -0
- package/dist/components/export/Export.js.map +1 -0
- package/dist/components/export/Export.mjs +213 -0
- package/dist/components/export/Export.mjs.map +1 -0
- package/dist/components/export/ExportWarning.d.ts +15 -0
- package/dist/components/export/ExportWarning.d.ts.map +1 -0
- package/dist/components/export/ExportWarning.js +141 -0
- package/dist/components/export/ExportWarning.js.map +1 -0
- package/dist/components/export/ExportWarning.mjs +174 -0
- package/dist/components/export/ExportWarning.mjs.map +1 -0
- package/dist/components/import/Import.d.ts +20 -0
- package/dist/components/import/Import.d.ts.map +1 -0
- package/dist/components/import/Import.js +290 -0
- package/dist/components/import/Import.js.map +1 -0
- package/dist/components/import/Import.mjs +422 -0
- package/dist/components/import/Import.mjs.map +1 -0
- package/dist/components/onramp/OnRamp.d.ts +14 -0
- package/dist/components/onramp/OnRamp.d.ts.map +1 -0
- package/dist/components/onramp/OnRamp.js +61 -0
- package/dist/components/onramp/OnRamp.js.map +1 -0
- package/dist/components/onramp/OnRamp.mjs +79 -0
- package/dist/components/onramp/OnRamp.mjs.map +1 -0
- package/dist/components/send-transaction/SendTransaction.d.ts +12 -0
- package/dist/components/send-transaction/SendTransaction.d.ts.map +1 -0
- package/dist/components/send-transaction/SendTransaction.js +65 -0
- package/dist/components/send-transaction/SendTransaction.js.map +1 -0
- package/dist/components/send-transaction/SendTransaction.mjs +89 -0
- package/dist/components/send-transaction/SendTransaction.mjs.map +1 -0
- package/dist/components/send-transaction/helpers.d.ts +4 -0
- package/dist/components/send-transaction/helpers.d.ts.map +1 -0
- package/dist/components/send-transaction/helpers.js +37 -0
- package/dist/components/send-transaction/helpers.js.map +1 -0
- package/dist/components/send-transaction/helpers.mjs +34 -0
- package/dist/components/send-transaction/helpers.mjs.map +1 -0
- package/dist/components/sign/Message.d.ts +18 -0
- package/dist/components/sign/Message.d.ts.map +1 -0
- package/dist/components/sign/Message.js +132 -0
- package/dist/components/sign/Message.js.map +1 -0
- package/dist/components/sign/Message.mjs +148 -0
- package/dist/components/sign/Message.mjs.map +1 -0
- package/dist/components/user/ConnectWallet.d.ts +8 -0
- package/dist/components/user/ConnectWallet.d.ts.map +1 -0
- package/dist/components/user/ConnectWallet.js +114 -0
- package/dist/components/user/ConnectWallet.js.map +1 -0
- package/dist/components/user/ConnectWallet.mjs +194 -0
- package/dist/components/user/ConnectWallet.mjs.map +1 -0
- package/dist/components/user/RemoveEmail.d.ts +12 -0
- package/dist/components/user/RemoveEmail.d.ts.map +1 -0
- package/dist/components/user/RemoveEmail.js +105 -0
- package/dist/components/user/RemoveEmail.js.map +1 -0
- package/dist/components/user/RemoveEmail.mjs +124 -0
- package/dist/components/user/RemoveEmail.mjs.map +1 -0
- package/dist/components/user/RemoveOAuthProvider.d.ts +12 -0
- package/dist/components/user/RemoveOAuthProvider.d.ts.map +1 -0
- package/dist/components/user/RemoveOAuthProvider.js +110 -0
- package/dist/components/user/RemoveOAuthProvider.js.map +1 -0
- package/dist/components/user/RemoveOAuthProvider.mjs +131 -0
- package/dist/components/user/RemoveOAuthProvider.mjs.map +1 -0
- package/dist/components/user/RemovePasskey.d.ts +12 -0
- package/dist/components/user/RemovePasskey.d.ts.map +1 -0
- package/dist/components/user/RemovePasskey.js +114 -0
- package/dist/components/user/RemovePasskey.js.map +1 -0
- package/dist/components/user/RemovePasskey.mjs +135 -0
- package/dist/components/user/RemovePasskey.mjs.map +1 -0
- package/dist/components/user/RemovePhoneNumber.d.ts +12 -0
- package/dist/components/user/RemovePhoneNumber.d.ts.map +1 -0
- package/dist/components/user/RemovePhoneNumber.js +105 -0
- package/dist/components/user/RemovePhoneNumber.js.map +1 -0
- package/dist/components/user/RemovePhoneNumber.mjs +124 -0
- package/dist/components/user/RemovePhoneNumber.mjs.map +1 -0
- package/dist/components/user/UpdateEmail.d.ts +12 -0
- package/dist/components/user/UpdateEmail.d.ts.map +1 -0
- package/dist/components/user/UpdateEmail.js +154 -0
- package/dist/components/user/UpdateEmail.js.map +1 -0
- package/dist/components/user/UpdateEmail.mjs +197 -0
- package/dist/components/user/UpdateEmail.mjs.map +1 -0
- package/dist/components/user/UpdatePhoneNumber.d.ts +12 -0
- package/dist/components/user/UpdatePhoneNumber.d.ts.map +1 -0
- package/dist/components/user/UpdatePhoneNumber.js +151 -0
- package/dist/components/user/UpdatePhoneNumber.js.map +1 -0
- package/dist/components/user/UpdatePhoneNumber.mjs +198 -0
- package/dist/components/user/UpdatePhoneNumber.mjs.map +1 -0
- package/dist/components/user/UpdateUserName.d.ts +13 -0
- package/dist/components/user/UpdateUserName.d.ts.map +1 -0
- package/dist/components/user/UpdateUserName.js +113 -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/components/verify/Verify.d.ts +9 -0
- package/dist/components/verify/Verify.d.ts.map +1 -0
- package/dist/components/verify/Verify.js +121 -0
- package/dist/components/verify/Verify.js.map +1 -0
- package/dist/components/verify/Verify.mjs +149 -0
- package/dist/components/verify/Verify.mjs.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +8 -0
- package/dist/index.mjs.map +1 -0
- package/dist/providers/ZeroXKeyProvider.d.ts +9 -0
- package/dist/providers/ZeroXKeyProvider.d.ts.map +1 -0
- package/dist/providers/ZeroXKeyProvider.js +36 -0
- package/dist/providers/ZeroXKeyProvider.js.map +1 -0
- package/dist/providers/ZeroXKeyProvider.mjs +34 -0
- package/dist/providers/ZeroXKeyProvider.mjs.map +1 -0
- package/dist/providers/client/Hook.d.ts +4 -0
- package/dist/providers/client/Hook.d.ts.map +1 -0
- package/dist/providers/client/Hook.js +15 -0
- package/dist/providers/client/Hook.js.map +1 -0
- package/dist/providers/client/Hook.mjs +13 -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 +3934 -0
- package/dist/providers/client/Provider.js.map +1 -0
- package/dist/providers/client/Provider.mjs +6895 -0
- package/dist/providers/client/Provider.mjs.map +1 -0
- package/dist/providers/client/Types.d.ts +711 -0
- package/dist/providers/client/Types.d.ts.map +1 -0
- package/dist/providers/client/Types.js +10 -0
- package/dist/providers/client/Types.js.map +1 -0
- package/dist/providers/client/Types.mjs +8 -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 +4 -0
- package/dist/providers/modal/Hook.d.ts.map +1 -0
- package/dist/providers/modal/Hook.js +15 -0
- package/dist/providers/modal/Hook.js.map +1 -0
- package/dist/providers/modal/Hook.mjs +13 -0
- package/dist/providers/modal/Hook.mjs.map +1 -0
- package/dist/providers/modal/Provider.d.ts +27 -0
- package/dist/providers/modal/Provider.d.ts.map +1 -0
- package/dist/providers/modal/Provider.js +48 -0
- package/dist/providers/modal/Provider.js.map +1 -0
- package/dist/providers/modal/Provider.mjs +68 -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 +345 -0
- package/dist/providers/modal/Root.js.map +1 -0
- package/dist/providers/modal/Root.mjs +352 -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/tests/oauth-test.d.ts +2 -0
- package/dist/tests/oauth-test.d.ts.map +1 -0
- package/dist/tests/timers-test.d.ts +2 -0
- package/dist/tests/timers-test.d.ts.map +1 -0
- package/dist/tests/utils-test.d.ts +2 -0
- package/dist/tests/utils-test.d.ts.map +1 -0
- package/dist/typedoc-entry/index.d.ts +5 -0
- package/dist/typedoc-entry/index.d.ts.map +1 -0
- package/dist/types/base.d.ts +178 -0
- package/dist/types/base.d.ts.map +1 -0
- package/dist/types/base.js +55 -0
- package/dist/types/base.js.map +1 -0
- package/dist/types/base.mjs +50 -0
- package/dist/types/base.mjs.map +1 -0
- package/dist/types/method-types.d.ts +258 -0
- package/dist/types/method-types.d.ts.map +1 -0
- package/dist/utils/oauth/completion.d.ts +132 -0
- package/dist/utils/oauth/completion.d.ts.map +1 -0
- package/dist/utils/oauth/completion.js +136 -0
- package/dist/utils/oauth/completion.js.map +1 -0
- package/dist/utils/oauth/completion.mjs +176 -0
- package/dist/utils/oauth/completion.mjs.map +1 -0
- package/dist/utils/oauth/config.d.ts +34 -0
- package/dist/utils/oauth/config.d.ts.map +1 -0
- package/dist/utils/oauth/config.js +69 -0
- package/dist/utils/oauth/config.js.map +1 -0
- package/dist/utils/oauth/config.mjs +54 -0
- package/dist/utils/oauth/config.mjs.map +1 -0
- package/dist/utils/oauth/helpers.d.ts +13 -0
- package/dist/utils/oauth/helpers.d.ts.map +1 -0
- package/dist/utils/oauth/helpers.js +38 -0
- package/dist/utils/oauth/helpers.js.map +1 -0
- package/dist/utils/oauth/helpers.mjs +35 -0
- package/dist/utils/oauth/helpers.mjs.map +1 -0
- package/dist/utils/oauth/index.d.ts +7 -0
- package/dist/utils/oauth/index.d.ts.map +1 -0
- package/dist/utils/oauth/pkce.d.ts +14 -0
- package/dist/utils/oauth/pkce.d.ts.map +1 -0
- package/dist/utils/oauth/pkce.js +48 -0
- package/dist/utils/oauth/pkce.js.map +1 -0
- package/dist/utils/oauth/pkce.mjs +85 -0
- package/dist/utils/oauth/pkce.mjs.map +1 -0
- package/dist/utils/oauth/storage.d.ts +48 -0
- package/dist/utils/oauth/storage.d.ts.map +1 -0
- package/dist/utils/oauth/storage.js +87 -0
- package/dist/utils/oauth/storage.js.map +1 -0
- package/dist/utils/oauth/storage.mjs +78 -0
- package/dist/utils/oauth/storage.mjs.map +1 -0
- package/dist/utils/oauth/url.d.ts +94 -0
- package/dist/utils/oauth/url.d.ts.map +1 -0
- package/dist/utils/oauth/url.js +224 -0
- package/dist/utils/oauth/url.js.map +1 -0
- package/dist/utils/oauth/url.mjs +230 -0
- package/dist/utils/oauth/url.mjs.map +1 -0
- package/dist/utils/timers.d.ts +73 -0
- package/dist/utils/timers.d.ts.map +1 -0
- package/dist/utils/timers.js +133 -0
- package/dist/utils/timers.js.map +1 -0
- package/dist/utils/timers.mjs +142 -0
- package/dist/utils/timers.mjs.map +1 -0
- package/dist/utils/utils.d.ts +40 -0
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/utils/utils.js +116 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/utils/utils.mjs +164 -0
- package/dist/utils/utils.mjs.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1,3934 @@
|
|
|
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 storage = require('../../utils/oauth/storage.js');
|
|
8
|
+
require('../../utils/oauth/config.js');
|
|
9
|
+
var url = require('../../utils/oauth/url.js');
|
|
10
|
+
var completion = require('../../utils/oauth/completion.js');
|
|
11
|
+
var pkce = require('../../utils/oauth/pkce.js');
|
|
12
|
+
var helpers = require('../../utils/oauth/helpers.js');
|
|
13
|
+
var utils = require('../../utils/utils.js');
|
|
14
|
+
var timers = require('../../utils/timers.js');
|
|
15
|
+
var core = require('@0xkey-io/core');
|
|
16
|
+
var react = require('react');
|
|
17
|
+
var sdkTypes = require('@0xkey-io/sdk-types');
|
|
18
|
+
var Hook = require('../modal/Hook.js');
|
|
19
|
+
var base = require('../../types/base.js');
|
|
20
|
+
var index = require('../../components/auth/index.js');
|
|
21
|
+
var reactFontawesome = require('@fortawesome/react-fontawesome');
|
|
22
|
+
var Action = require('../../components/auth/Action.js');
|
|
23
|
+
var Message = require('../../components/sign/Message.js');
|
|
24
|
+
var Export = require('../../components/export/Export.js');
|
|
25
|
+
var Import = require('../../components/import/Import.js');
|
|
26
|
+
var Success = require('../../components/design/Success.js');
|
|
27
|
+
var UpdateEmail = require('../../components/user/UpdateEmail.js');
|
|
28
|
+
var UpdatePhoneNumber = require('../../components/user/UpdatePhoneNumber.js');
|
|
29
|
+
var UpdateUserName = require('../../components/user/UpdateUserName.js');
|
|
30
|
+
var RemoveOAuthProvider = require('../../components/user/RemoveOAuthProvider.js');
|
|
31
|
+
var RemovePasskey = require('../../components/user/RemovePasskey.js');
|
|
32
|
+
var ConnectWallet = require('../../components/user/ConnectWallet.js');
|
|
33
|
+
var Types = require('./Types.js');
|
|
34
|
+
var OTP = require('../../components/auth/OTP.js');
|
|
35
|
+
var RemoveEmail = require('../../components/user/RemoveEmail.js');
|
|
36
|
+
var RemovePhoneNumber = require('../../components/user/RemovePhoneNumber.js');
|
|
37
|
+
var Verify = require('../../components/verify/Verify.js');
|
|
38
|
+
var OnRamp = require('../../components/onramp/OnRamp.js');
|
|
39
|
+
var Svg = require('../../components/design/Svg.js');
|
|
40
|
+
var SendTransaction = require('../../components/send-transaction/SendTransaction.js');
|
|
41
|
+
var helpers$1 = require('../../components/send-transaction/helpers.js');
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Provides ZeroXKey client authentication, session management, wallet operations, and user profile management
|
|
45
|
+
* for the React Wallet Kit SDK. This context provider encapsulates all core authentication flows (Passkey, Wallet, OTP, OAuth),
|
|
46
|
+
* session lifecycle (creation, expiration, refresh), wallet connecting/import/export, and user profile updates (email, phone, name).
|
|
47
|
+
*
|
|
48
|
+
* The provider automatically initializes the ZeroXKey client, fetches configuration (including proxy auth config if needed),
|
|
49
|
+
* and synchronizes session and authentication state. It exposes a comprehensive set of methods for authentication flows,
|
|
50
|
+
* wallet management, and user profile operations, as well as UI handlers for modal-driven flows.
|
|
51
|
+
*
|
|
52
|
+
* Features:
|
|
53
|
+
* - Passkey, Wallet, OTP (Email/SMS), and OAuth (Google, Apple, Facebook, X, Discord) authentication and sign-up flows.
|
|
54
|
+
* - Session management: creation, expiration scheduling, refresh, and clearing.
|
|
55
|
+
* - Wallet management: fetch, connect, import, export, account management.
|
|
56
|
+
* - User profile management: email, phone, name, OAuth provider, and passkey linking/removal.
|
|
57
|
+
* - Modal-driven UI flows for authentication, wallet connecting, and profile updates.
|
|
58
|
+
* - Error handling and callback integration for custom error and event responses.
|
|
59
|
+
*
|
|
60
|
+
* Usage:
|
|
61
|
+
* Wrap your application with `ZeroXKeyProvider` to enable authentication and wallet features via context.
|
|
62
|
+
*
|
|
63
|
+
* @param config - The ZeroXKey provider configuration object.
|
|
64
|
+
* @param children - React children to be rendered within the provider.
|
|
65
|
+
* @param callbacks - Optional callbacks for error handling and session events.
|
|
66
|
+
*
|
|
67
|
+
* @returns A React context provider exposing authentication, wallet, and user management methods and state.
|
|
68
|
+
*/
|
|
69
|
+
const ClientProvider = ({
|
|
70
|
+
config,
|
|
71
|
+
children,
|
|
72
|
+
callbacks
|
|
73
|
+
}) => {
|
|
74
|
+
const [client, setClient] = react.useState(undefined);
|
|
75
|
+
const [session, setSession] = react.useState(undefined);
|
|
76
|
+
const [masterConfig, setMasterConfig] = react.useState(undefined);
|
|
77
|
+
const [wallets, setWallets] = react.useState([]);
|
|
78
|
+
const [user, setUser] = react.useState(undefined);
|
|
79
|
+
const [clientState, setClientState] = react.useState();
|
|
80
|
+
const [authState, setAuthState] = react.useState(base.AuthState.Unauthenticated);
|
|
81
|
+
// if there is no authProxyConfigId or if autoFetchWalletKitConfig is specifically
|
|
82
|
+
// set to false, we don't need to fetch the config
|
|
83
|
+
const shouldFetchWalletKitConfig = !!config.authProxyConfigId && (config.autoFetchWalletKitConfig ?? true);
|
|
84
|
+
// we use this custom hook to only update the state if the value is different
|
|
85
|
+
// this is so our useEffect that calls `initializeWalletProviderListeners()` only runs when it needs to
|
|
86
|
+
const [walletProviders, setWalletProviders] = utils.useWalletProviderState();
|
|
87
|
+
const expiryTimeoutsRef = react.useRef({});
|
|
88
|
+
const proxyAuthConfigRef = react.useRef(null);
|
|
89
|
+
const [allSessions, setAllSessions] = react.useState(undefined);
|
|
90
|
+
const {
|
|
91
|
+
isMobile,
|
|
92
|
+
pushPage,
|
|
93
|
+
popPage,
|
|
94
|
+
closeModal
|
|
95
|
+
} = Hook.useModal();
|
|
96
|
+
const completeRedirectOauth = async () => {
|
|
97
|
+
// Since we use localStorage (see storage.ts), we always clean up OAuth data
|
|
98
|
+
// when this runs — even if there are no OAuth params in the URL (e.g. the
|
|
99
|
+
// user canceled at the provider and came back manually)
|
|
100
|
+
try {
|
|
101
|
+
// Check for either hash or search parameters that could indicate an OAuth redirect
|
|
102
|
+
if (!window.location.hash && !window.location.search) {
|
|
103
|
+
// No OAuth redirect parameters found, nothing to do
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Wraps an OAuth completion action with optional modal UI.
|
|
108
|
+
* This is the key difference between redirect and popup flows:
|
|
109
|
+
* - Popup: No modal needed (the popup window itself is the UI)
|
|
110
|
+
* - Redirect: Optional modal to show loading/success states on return
|
|
111
|
+
*/
|
|
112
|
+
const withModalWrapper = async params => {
|
|
113
|
+
const {
|
|
114
|
+
provider,
|
|
115
|
+
isAddProvider,
|
|
116
|
+
metadata,
|
|
117
|
+
openModal,
|
|
118
|
+
action
|
|
119
|
+
} = params;
|
|
120
|
+
const providerDisplayName = helpers.capitalizeProviderName(provider);
|
|
121
|
+
const icon = helpers.getProviderIcon(provider);
|
|
122
|
+
if (openModal === "true") {
|
|
123
|
+
// Show modal UI for the completion
|
|
124
|
+
await new Promise((resolve, reject) => {
|
|
125
|
+
pushPage({
|
|
126
|
+
key: `${providerDisplayName} OAuth`,
|
|
127
|
+
content: jsxRuntime.jsx(Action.ActionPage, {
|
|
128
|
+
closeOnComplete: isAddProvider ? false : true,
|
|
129
|
+
title: isAddProvider ? `Adding ${providerDisplayName} provider...` : `Authenticating with ${providerDisplayName}...`,
|
|
130
|
+
action: async () => {
|
|
131
|
+
try {
|
|
132
|
+
await action();
|
|
133
|
+
if (isAddProvider && metadata) {
|
|
134
|
+
// Don't show success for auth. Not needed
|
|
135
|
+
pushPage({
|
|
136
|
+
key: "OAuth Provider Added",
|
|
137
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
138
|
+
text: `Successfully added ${providerDisplayName} OAuth provider!`,
|
|
139
|
+
duration: metadata.successPageDuration ?? 2000,
|
|
140
|
+
onComplete: () => {
|
|
141
|
+
closeModal();
|
|
142
|
+
}
|
|
143
|
+
}),
|
|
144
|
+
preventBack: true,
|
|
145
|
+
showTitle: false
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
resolve();
|
|
149
|
+
} catch (err) {
|
|
150
|
+
reject(err);
|
|
151
|
+
popPage();
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, {
|
|
155
|
+
icon: icon,
|
|
156
|
+
size: "3x"
|
|
157
|
+
})
|
|
158
|
+
}),
|
|
159
|
+
showTitle: false,
|
|
160
|
+
onClose: () => {
|
|
161
|
+
reject(new sdkTypes.ZeroXKeyError(isAddProvider ? `User canceled the ${providerDisplayName} add provider process.` : `User canceled the ${providerDisplayName} authentication process.`, sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED));
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
} else {
|
|
166
|
+
// No modal - execute directly
|
|
167
|
+
await action();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
// Handle PKCE-based OAuth redirects (Facebook, Discord, X) with code in search parameters
|
|
171
|
+
if (window.location.search && window.location.search.includes("code=") && window.location.search.includes("state=")) {
|
|
172
|
+
// Parse the URL using our unified helper
|
|
173
|
+
const result = url.parseOAuthResponse(window.location.href);
|
|
174
|
+
if (!result || !result.authCode || !result.publicKey) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (result.flow !== "redirect") {
|
|
178
|
+
// To complete OAuth we need redirect flow
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const {
|
|
182
|
+
authCode: code,
|
|
183
|
+
provider,
|
|
184
|
+
publicKey,
|
|
185
|
+
oauthIntent,
|
|
186
|
+
sessionKey,
|
|
187
|
+
nonce,
|
|
188
|
+
openModal
|
|
189
|
+
} = result;
|
|
190
|
+
const isAddProvider = oauthIntent === storage.OAUTH_INTENT_ADD_PROVIDER;
|
|
191
|
+
const metadata = isAddProvider ? storage.getOAuthAddProviderMetadata() : null;
|
|
192
|
+
/**
|
|
193
|
+
* Helper to complete PKCE redirect flow with optional modal wrapper.
|
|
194
|
+
* Uses completePKCEFlow from oauth utils for the core logic.
|
|
195
|
+
* We put this in a separate function to avoid duplicating for each provider.
|
|
196
|
+
*/
|
|
197
|
+
const completePKCERedirect = async (providerName, exchangeCodeFn) => {
|
|
198
|
+
const action = async () => {
|
|
199
|
+
try {
|
|
200
|
+
await completion.completePKCEFlow({
|
|
201
|
+
publicKey,
|
|
202
|
+
providerName,
|
|
203
|
+
sessionKey: sessionKey ?? undefined,
|
|
204
|
+
callbacks,
|
|
205
|
+
completeOauth,
|
|
206
|
+
onAddProvider:
|
|
207
|
+
// Only set onAddProvider if we are adding a provider and have metadata
|
|
208
|
+
isAddProvider && metadata ? async oidcToken => {
|
|
209
|
+
await addOauthProvider({
|
|
210
|
+
providerName: provider,
|
|
211
|
+
oidcToken,
|
|
212
|
+
organizationId: metadata.organizationId,
|
|
213
|
+
userId: metadata.userId,
|
|
214
|
+
...(metadata.stampWith && {
|
|
215
|
+
stampWith: metadata.stampWith
|
|
216
|
+
})
|
|
217
|
+
});
|
|
218
|
+
} : undefined,
|
|
219
|
+
exchangeCodeForToken: exchangeCodeFn
|
|
220
|
+
});
|
|
221
|
+
} catch (err) {
|
|
222
|
+
if (callbacks?.onError) {
|
|
223
|
+
const providerDisplayName = helpers.capitalizeProviderName(providerName);
|
|
224
|
+
callbacks.onError(err instanceof sdkTypes.ZeroXKeyError ? err : new sdkTypes.ZeroXKeyError(`${providerDisplayName} authentication failed`, sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR, err));
|
|
225
|
+
}
|
|
226
|
+
throw err;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
await withModalWrapper({
|
|
230
|
+
provider: providerName,
|
|
231
|
+
isAddProvider,
|
|
232
|
+
metadata,
|
|
233
|
+
openModal,
|
|
234
|
+
action
|
|
235
|
+
});
|
|
236
|
+
// Clean up URL after successful completion
|
|
237
|
+
url.cleanupOAuthUrl();
|
|
238
|
+
};
|
|
239
|
+
// FACEBOOK
|
|
240
|
+
if (provider === sdkTypes.OAuthProviders.FACEBOOK) {
|
|
241
|
+
const clientId = masterConfig?.auth?.oauthConfig?.facebookClientId;
|
|
242
|
+
const redirectURI = masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
|
|
243
|
+
const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.FACEBOOK);
|
|
244
|
+
if (clientId && redirectURI && hasVerifier) {
|
|
245
|
+
await completePKCERedirect(sdkTypes.OAuthProviders.FACEBOOK, async codeVerifier => {
|
|
246
|
+
const tokenResponse = await pkce.exchangeFacebookCodeForToken(clientId, redirectURI, code, codeVerifier);
|
|
247
|
+
const oidcToken = tokenResponse?.id_token;
|
|
248
|
+
if (!oidcToken) {
|
|
249
|
+
throw new sdkTypes.ZeroXKeyError("Missing OIDC token", sdkTypes.ZeroXKeyErrorCodes.OAUTH_LOGIN_ERROR);
|
|
250
|
+
}
|
|
251
|
+
return oidcToken;
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
// DISCORD
|
|
257
|
+
if (provider === sdkTypes.OAuthProviders.DISCORD) {
|
|
258
|
+
const clientId = masterConfig?.auth?.oauthConfig?.discordClientId;
|
|
259
|
+
const redirectURI = result.redirectUri ?? masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
|
|
260
|
+
const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.DISCORD);
|
|
261
|
+
if (clientId && redirectURI && hasVerifier && nonce) {
|
|
262
|
+
await completePKCERedirect(sdkTypes.OAuthProviders.DISCORD, async codeVerifier => {
|
|
263
|
+
const resp = await client?.httpClient.proxyOAuth2Authenticate({
|
|
264
|
+
provider: "OAUTH2_PROVIDER_DISCORD",
|
|
265
|
+
authCode: code,
|
|
266
|
+
redirectUri: redirectURI,
|
|
267
|
+
codeVerifier,
|
|
268
|
+
clientId,
|
|
269
|
+
nonce
|
|
270
|
+
});
|
|
271
|
+
const oidcToken = resp?.oidcToken;
|
|
272
|
+
if (!oidcToken) {
|
|
273
|
+
throw new sdkTypes.ZeroXKeyError("Missing OIDC token", sdkTypes.ZeroXKeyErrorCodes.OAUTH_LOGIN_ERROR);
|
|
274
|
+
}
|
|
275
|
+
return oidcToken;
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
// X (Twitter)
|
|
281
|
+
if (provider === sdkTypes.OAuthProviders.X) {
|
|
282
|
+
const clientId = masterConfig?.auth?.oauthConfig?.xClientId;
|
|
283
|
+
const redirectURI = result.redirectUri ?? masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
|
|
284
|
+
const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.X);
|
|
285
|
+
if (clientId && redirectURI && hasVerifier && nonce) {
|
|
286
|
+
await completePKCERedirect(sdkTypes.OAuthProviders.X, async codeVerifier => {
|
|
287
|
+
const resp = await client?.httpClient.proxyOAuth2Authenticate({
|
|
288
|
+
provider: "OAUTH2_PROVIDER_X",
|
|
289
|
+
authCode: code,
|
|
290
|
+
redirectUri: redirectURI,
|
|
291
|
+
codeVerifier,
|
|
292
|
+
clientId,
|
|
293
|
+
nonce
|
|
294
|
+
});
|
|
295
|
+
const oidcToken = resp?.oidcToken;
|
|
296
|
+
if (!oidcToken) {
|
|
297
|
+
throw new sdkTypes.ZeroXKeyError("Missing OIDC token", sdkTypes.ZeroXKeyErrorCodes.OAUTH_LOGIN_ERROR);
|
|
298
|
+
}
|
|
299
|
+
return oidcToken;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// Handle Google/Apple redirects (uses hash with idToken - non-PKCE)
|
|
306
|
+
if (window.location.hash) {
|
|
307
|
+
// Parse the URL using our unified helper
|
|
308
|
+
const result = url.parseOAuthResponse(window.location.href);
|
|
309
|
+
if (!result || !result.idToken || result.flow !== "redirect" || !result.publicKey) {
|
|
310
|
+
// idToken and publicKey are required to complete OAuth. These are both in the hash for non-PKCE providers
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const {
|
|
314
|
+
idToken,
|
|
315
|
+
provider,
|
|
316
|
+
publicKey,
|
|
317
|
+
openModal,
|
|
318
|
+
sessionKey,
|
|
319
|
+
oauthIntent
|
|
320
|
+
} = result;
|
|
321
|
+
const isAddProvider = oauthIntent === storage.OAUTH_INTENT_ADD_PROVIDER;
|
|
322
|
+
const metadata = isAddProvider ? storage.getOAuthAddProviderMetadata() : null;
|
|
323
|
+
const resolvedProvider = provider || sdkTypes.OAuthProviders.GOOGLE;
|
|
324
|
+
// Use completeOAuthFlow from utils for the core completion logic
|
|
325
|
+
const action = async () => {
|
|
326
|
+
await completion.completeOAuthFlow({
|
|
327
|
+
provider: resolvedProvider,
|
|
328
|
+
publicKey,
|
|
329
|
+
oidcToken: idToken,
|
|
330
|
+
sessionKey: sessionKey ?? undefined,
|
|
331
|
+
callbacks,
|
|
332
|
+
completeOauth,
|
|
333
|
+
onAddProvider: isAddProvider && metadata ? async oidcToken => {
|
|
334
|
+
await addOauthProvider({
|
|
335
|
+
providerName: resolvedProvider,
|
|
336
|
+
oidcToken,
|
|
337
|
+
organizationId: metadata.organizationId,
|
|
338
|
+
userId: metadata.userId,
|
|
339
|
+
...(metadata.stampWith && {
|
|
340
|
+
stampWith: metadata.stampWith
|
|
341
|
+
})
|
|
342
|
+
});
|
|
343
|
+
} : undefined
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
await withModalWrapper({
|
|
347
|
+
provider: resolvedProvider,
|
|
348
|
+
isAddProvider,
|
|
349
|
+
metadata,
|
|
350
|
+
openModal: openModal ?? undefined,
|
|
351
|
+
action
|
|
352
|
+
});
|
|
353
|
+
// Clean up the URL after processing
|
|
354
|
+
url.cleanupOAuthUrlPreserveSearch();
|
|
355
|
+
}
|
|
356
|
+
} finally {
|
|
357
|
+
storage.clearAllOAuthData();
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
const buildConfig = proxyAuthConfig => {
|
|
361
|
+
// Juggle the local overrides with the values set in the dashboard (proxyAuthConfig).
|
|
362
|
+
const resolvedMethods = {
|
|
363
|
+
emailOtpAuthEnabled: config.auth?.methods?.emailOtpAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("email"),
|
|
364
|
+
smsOtpAuthEnabled: config.auth?.methods?.smsOtpAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("sms"),
|
|
365
|
+
passkeyAuthEnabled: config.auth?.methods?.passkeyAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("passkey"),
|
|
366
|
+
walletAuthEnabled: config.auth?.methods?.walletAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("wallet"),
|
|
367
|
+
googleOauthEnabled: config.auth?.methods?.googleOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("google"),
|
|
368
|
+
xOauthEnabled: config.auth?.methods?.xOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("x"),
|
|
369
|
+
discordOauthEnabled: config.auth?.methods?.discordOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("discord"),
|
|
370
|
+
appleOauthEnabled: config.auth?.methods?.appleOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("apple"),
|
|
371
|
+
facebookOauthEnabled: config.auth?.methods?.facebookOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("facebook")
|
|
372
|
+
};
|
|
373
|
+
const resolvedClientIds = {
|
|
374
|
+
googleClientId: config.auth?.oauthConfig?.googleClientId ?? proxyAuthConfig?.oauthClientIds?.google,
|
|
375
|
+
appleClientId: config.auth?.oauthConfig?.appleClientId ?? proxyAuthConfig?.oauthClientIds?.apple,
|
|
376
|
+
facebookClientId: config.auth?.oauthConfig?.facebookClientId ?? proxyAuthConfig?.oauthClientIds?.facebook,
|
|
377
|
+
xClientId: config.auth?.oauthConfig?.xClientId ?? proxyAuthConfig?.oauthClientIds?.x,
|
|
378
|
+
discordClientId: config.auth?.oauthConfig?.discordClientId ?? proxyAuthConfig?.oauthClientIds?.discord
|
|
379
|
+
};
|
|
380
|
+
const redirectUrl = config.auth?.oauthConfig?.oauthRedirectUri ?? proxyAuthConfig?.oauthRedirectUrl;
|
|
381
|
+
// Set a default ordering for the oAuth methods
|
|
382
|
+
const oauthOrder = config.auth?.oauthOrder ?? ["google", "apple", "x", "discord", "facebook"].filter(provider => resolvedMethods[`${provider}OauthEnabled`]);
|
|
383
|
+
// Set a default ordering for the overall auth methods
|
|
384
|
+
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);
|
|
385
|
+
// Warn if they are trying to set auth proxy only settings directly
|
|
386
|
+
if (proxyAuthConfig) {
|
|
387
|
+
if (config.auth?.sessionExpirationSeconds) {
|
|
388
|
+
console.warn("ZeroXKey SDK warning. You have set sessionExpirationSeconds directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure session expiration in the ZeroXKey dashboard.");
|
|
389
|
+
}
|
|
390
|
+
if (config.auth?.otpAlphanumeric !== undefined) {
|
|
391
|
+
console.warn("ZeroXKey SDK warning. You have set otpAlphanumeric directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the ZeroXKey dashboard.");
|
|
392
|
+
}
|
|
393
|
+
if (config.auth?.otpLength) {
|
|
394
|
+
console.warn("ZeroXKey SDK warning. You have set otpLength directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the ZeroXKey dashboard.");
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// These are settings that, if using the auth proxy, must be set in the dashboard. They override any local settings unless they are not using auth proxy or are not fetching the auth proxy config.
|
|
398
|
+
const authProxyPrioSettings = {
|
|
399
|
+
sessionExpirationSeconds: proxyAuthConfig?.sessionExpirationSeconds ?? config.auth?.sessionExpirationSeconds,
|
|
400
|
+
otpAlphanumeric: proxyAuthConfig?.otpAlphanumeric ?? config.auth?.otpAlphanumeric ?? true,
|
|
401
|
+
otpLength: proxyAuthConfig?.otpLength ?? config.auth?.otpLength ?? "6"
|
|
402
|
+
};
|
|
403
|
+
return {
|
|
404
|
+
...config,
|
|
405
|
+
// Overrides:
|
|
406
|
+
auth: {
|
|
407
|
+
...config.auth,
|
|
408
|
+
...authProxyPrioSettings,
|
|
409
|
+
methods: resolvedMethods,
|
|
410
|
+
oauthConfig: {
|
|
411
|
+
...config.auth?.oauthConfig,
|
|
412
|
+
...resolvedClientIds,
|
|
413
|
+
oauthRedirectUri: redirectUrl,
|
|
414
|
+
// on mobile we default to true since many mobile browsers
|
|
415
|
+
// (e.g. Safari) block popups
|
|
416
|
+
openOauthInPage: isMobile ? true : config.auth?.oauthConfig?.openOauthInPage
|
|
417
|
+
},
|
|
418
|
+
methodOrder,
|
|
419
|
+
oauthOrder,
|
|
420
|
+
autoRefreshSession: config.auth?.autoRefreshSession ?? true
|
|
421
|
+
},
|
|
422
|
+
autoRefreshManagedState: config.autoRefreshManagedState ?? true,
|
|
423
|
+
walletConfig: {
|
|
424
|
+
...config.walletConfig,
|
|
425
|
+
features: {
|
|
426
|
+
...config.walletConfig?.features,
|
|
427
|
+
auth:
|
|
428
|
+
// 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.
|
|
429
|
+
resolvedMethods.walletAuthEnabled ?? config.walletConfig?.features?.auth ?? true,
|
|
430
|
+
connecting: config.walletConfig?.features?.connecting ?? true // Default connecting to true if not set. We don't care about auth settings here.
|
|
431
|
+
},
|
|
432
|
+
chains: {
|
|
433
|
+
...config.walletConfig?.chains,
|
|
434
|
+
ethereum: {
|
|
435
|
+
...config.walletConfig?.chains?.ethereum,
|
|
436
|
+
// keep user's value if provided; default only when undefined
|
|
437
|
+
native: config.walletConfig?.chains?.ethereum?.native ?? true
|
|
438
|
+
},
|
|
439
|
+
solana: {
|
|
440
|
+
...config.walletConfig?.chains?.solana,
|
|
441
|
+
// keep user's value if provided; default only when undefined
|
|
442
|
+
native: config.walletConfig?.chains?.solana?.native ?? true
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
importIframeUrl: config.importIframeUrl ?? "https://import.0xkey.com",
|
|
447
|
+
exportIframeUrl: config.exportIframeUrl ?? "https://export.0xkey.com"
|
|
448
|
+
};
|
|
449
|
+
};
|
|
450
|
+
/**
|
|
451
|
+
* Initializes the ZeroXKey client with the provided configuration.
|
|
452
|
+
* This function sets up the client, fetches the proxy auth config if needed,
|
|
453
|
+
* and prepares the client for use in authentication and wallet operations.
|
|
454
|
+
*
|
|
455
|
+
* @internal
|
|
456
|
+
*/
|
|
457
|
+
const initializeClient = async () => {
|
|
458
|
+
if (!masterConfig || client || clientState == base.ClientState.Loading) return;
|
|
459
|
+
try {
|
|
460
|
+
setClientState(base.ClientState.Loading);
|
|
461
|
+
const zeroXKeyClient = new core.ZeroXKeyClient({
|
|
462
|
+
apiBaseUrl: masterConfig.apiBaseUrl,
|
|
463
|
+
authProxyUrl: masterConfig.authProxyUrl,
|
|
464
|
+
authProxyConfigId: masterConfig.authProxyConfigId,
|
|
465
|
+
organizationId: masterConfig.organizationId,
|
|
466
|
+
// 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!
|
|
467
|
+
passkeyConfig: {
|
|
468
|
+
rpId: masterConfig.passkeyConfig?.rpId,
|
|
469
|
+
timeout: masterConfig.passkeyConfig?.timeout || 60000,
|
|
470
|
+
// 60 seconds
|
|
471
|
+
userVerification: masterConfig.passkeyConfig?.userVerification || "preferred",
|
|
472
|
+
allowCredentials: masterConfig.passkeyConfig?.allowCredentials || []
|
|
473
|
+
},
|
|
474
|
+
walletConfig: {
|
|
475
|
+
features: {
|
|
476
|
+
...masterConfig.walletConfig?.features
|
|
477
|
+
},
|
|
478
|
+
chains: {
|
|
479
|
+
...masterConfig.walletConfig?.chains
|
|
480
|
+
},
|
|
481
|
+
...(masterConfig.walletConfig?.walletConnect && {
|
|
482
|
+
walletConnect: masterConfig.walletConfig.walletConnect
|
|
483
|
+
})
|
|
484
|
+
},
|
|
485
|
+
defaultStamperType: masterConfig.defaultStamperType
|
|
486
|
+
});
|
|
487
|
+
await zeroXKeyClient.init();
|
|
488
|
+
setClient(zeroXKeyClient);
|
|
489
|
+
// Don't set clientState to ready until we fetch the proxy auth config (See other fetchProxyAuthConfig useEffect)
|
|
490
|
+
} catch (error) {
|
|
491
|
+
setClientState(base.ClientState.Error);
|
|
492
|
+
if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
|
|
493
|
+
callbacks?.onError?.(error);
|
|
494
|
+
} else {
|
|
495
|
+
callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize ZeroXKey client`, sdkTypes.ZeroXKeyErrorCodes.INITIALIZE_CLIENT_ERROR, error));
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
/**
|
|
500
|
+
* Initializes the user sessions by fetching all active sessions and setting up their state.
|
|
501
|
+
* @internal
|
|
502
|
+
*/
|
|
503
|
+
const initializeSessions = async () => {
|
|
504
|
+
setSession(undefined);
|
|
505
|
+
setAllSessions(undefined);
|
|
506
|
+
try {
|
|
507
|
+
const allLocalStorageSessions = await getAllSessions();
|
|
508
|
+
if (!allLocalStorageSessions) return;
|
|
509
|
+
await Promise.all(Object.keys(allLocalStorageSessions).map(async sessionKey => {
|
|
510
|
+
const session = allLocalStorageSessions?.[sessionKey];
|
|
511
|
+
if (!utils.isValidSession(session)) {
|
|
512
|
+
await clearSession({
|
|
513
|
+
sessionKey
|
|
514
|
+
});
|
|
515
|
+
if (sessionKey === (await getActiveSessionKey())) {
|
|
516
|
+
setSession(undefined);
|
|
517
|
+
}
|
|
518
|
+
delete allLocalStorageSessions[sessionKey];
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
scheduleSessionExpiration({
|
|
522
|
+
sessionKey,
|
|
523
|
+
expiry: session.expiry
|
|
524
|
+
});
|
|
525
|
+
}));
|
|
526
|
+
setAllSessions(allLocalStorageSessions || undefined);
|
|
527
|
+
const activeSessionKey = await client?.getActiveSessionKey();
|
|
528
|
+
if (activeSessionKey) {
|
|
529
|
+
// If we have an active session key, set
|
|
530
|
+
if (!allLocalStorageSessions[activeSessionKey]) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
setSession(allLocalStorageSessions[activeSessionKey]);
|
|
534
|
+
// we use `maybeFetchWallets()` instead of `maybeRefreshWallets()` here to avoid a race condition
|
|
535
|
+
// specifically, if WalletConnect finishes initializing before this promise resolves,
|
|
536
|
+
// `maybeRefreshWallets()` could overwrite the WalletConnect wallet state with an outdated
|
|
537
|
+
// list of wallets that doesn’t yet include the WalletConnect wallets
|
|
538
|
+
const [, wallets] = await Promise.all([maybeRefreshUser(), (() => {
|
|
539
|
+
if (!masterConfig?.autoRefreshManagedState) return [];
|
|
540
|
+
return fetchWallets();
|
|
541
|
+
})()]);
|
|
542
|
+
// the prev wallets should only ever be WalletConnect wallets
|
|
543
|
+
if (wallets) {
|
|
544
|
+
setWallets(prev => utils.mergeWalletsWithoutDuplicates(prev, wallets));
|
|
545
|
+
}
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
} catch (error) {
|
|
549
|
+
if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
|
|
550
|
+
callbacks?.onError?.(error);
|
|
551
|
+
} else {
|
|
552
|
+
callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize sessions`, sdkTypes.ZeroXKeyErrorCodes.INITIALIZE_SESSION_ERROR, error));
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
/**
|
|
557
|
+
* @internal
|
|
558
|
+
* Attach listeners for connected wallet providers so we can refresh state on changes.
|
|
559
|
+
*
|
|
560
|
+
* - Ethereum: listens for disconnect and chain/account changes to trigger a refresh.
|
|
561
|
+
* - Solana: listens for disconnect via Wallet Standard `change` events to trigger a refresh.
|
|
562
|
+
* - WalletConnect:
|
|
563
|
+
* - listens for disconnect and other state changes via its unified `change` event
|
|
564
|
+
* - additionally listens for `pairingExpired` events (proposal expiration), in which
|
|
565
|
+
* case we re-fetch providers to refresh the pairing URI for the UI.
|
|
566
|
+
*
|
|
567
|
+
* Notes:
|
|
568
|
+
* - Only connected providers are bound, except WalletConnect which must always register
|
|
569
|
+
* to handle proposal expiration even if no active session exists.
|
|
570
|
+
* - Since all WalletConnect providers share the same session, we only attach to one.
|
|
571
|
+
*
|
|
572
|
+
* @param walletProviders - Discovered providers; only connected ones are bound.
|
|
573
|
+
* @param onUpdateState - Invoked when a relevant provider event occurs.
|
|
574
|
+
* @returns Cleanup function that removes all listeners registered by this call.
|
|
575
|
+
*/
|
|
576
|
+
async function initializeWalletProviderListeners(walletProviders, onUpdateState) {
|
|
577
|
+
if (walletProviders.length === 0) return () => {};
|
|
578
|
+
const cleanups = [];
|
|
579
|
+
// we only want to initialize these listeners for connected walletProviders
|
|
580
|
+
const nativeOnly = provider => provider.interfaceType !== core.WalletInterfaceType.WalletConnect;
|
|
581
|
+
const ethProviders = masterConfig?.walletConfig?.chains.ethereum?.native ? walletProviders.filter(provider => provider.chainInfo.namespace === core.Chain.Ethereum && nativeOnly(provider) && provider.connectedAddresses.length > 0) : [];
|
|
582
|
+
const solProviders = masterConfig?.walletConfig?.chains.solana?.native ? walletProviders.filter(provider => provider.chainInfo.namespace === core.Chain.Solana && nativeOnly(provider) && provider.connectedAddresses.length > 0) : [];
|
|
583
|
+
// WalletConnect is excluded from native event wiring. Instead,
|
|
584
|
+
// it uses a unified `change` event exposed by our custom wrapper
|
|
585
|
+
//
|
|
586
|
+
// unlike native providers, we register listeners for WalletConnect
|
|
587
|
+
// even if it’s not currently “connected”. This is required so we
|
|
588
|
+
// can detect proposal expiration events and display the new regenerated
|
|
589
|
+
// URI for the UI
|
|
590
|
+
const wcProviders = walletProviders.filter(p => p.interfaceType === core.WalletInterfaceType.WalletConnect);
|
|
591
|
+
// since all WalletConnect providers share the same underlying session
|
|
592
|
+
// and emit identical events, we only attach listeners to a single provider
|
|
593
|
+
const wcProvider = wcProviders.find(p => p.interfaceType === core.WalletInterfaceType.WalletConnect);
|
|
594
|
+
function attachEthereumListeners(provider, onUpdateState) {
|
|
595
|
+
if (typeof provider.on !== "function") return;
|
|
596
|
+
const handleChainChanged = async _chainId => onUpdateState();
|
|
597
|
+
const handleAccountsChanged = async accounts => {
|
|
598
|
+
if (accounts.length === 0) onUpdateState();
|
|
599
|
+
};
|
|
600
|
+
const handleDisconnect = () => onUpdateState();
|
|
601
|
+
provider.on("chainChanged", handleChainChanged);
|
|
602
|
+
provider.on("accountsChanged", handleAccountsChanged);
|
|
603
|
+
provider.on("disconnect", handleDisconnect);
|
|
604
|
+
return () => {
|
|
605
|
+
provider.removeListener("chainChanged", handleChainChanged);
|
|
606
|
+
provider.removeListener("accountsChanged", handleAccountsChanged);
|
|
607
|
+
provider.removeListener("disconnect", handleDisconnect);
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
function attachSolanaListeners(provider, onUpdateState) {
|
|
611
|
+
const cleanups = [];
|
|
612
|
+
const walletEvents = provider?.features?.["standard:events"];
|
|
613
|
+
if (walletEvents?.on) {
|
|
614
|
+
const offChange = walletEvents.on("change", async _evt => {
|
|
615
|
+
await onUpdateState();
|
|
616
|
+
});
|
|
617
|
+
cleanups.push(offChange);
|
|
618
|
+
}
|
|
619
|
+
return () => cleanups.forEach(fn => fn());
|
|
620
|
+
}
|
|
621
|
+
ethProviders.forEach(p => {
|
|
622
|
+
const cleanup = attachEthereumListeners(p.provider, onUpdateState);
|
|
623
|
+
if (cleanup) cleanups.push(cleanup);
|
|
624
|
+
});
|
|
625
|
+
solProviders.forEach(p => {
|
|
626
|
+
const cleanup = attachSolanaListeners(p.provider, onUpdateState);
|
|
627
|
+
if (cleanup) cleanups.push(cleanup);
|
|
628
|
+
});
|
|
629
|
+
if (wcProvider) {
|
|
630
|
+
const standardEvents = wcProvider.provider?.features?.["standard:events"];
|
|
631
|
+
if (standardEvents?.on) {
|
|
632
|
+
if (standardEvents?.on) {
|
|
633
|
+
const unsubscribe = standardEvents.on("change", async evt => {
|
|
634
|
+
// if the event is a proposalExpired, we want to re-fetch the providers
|
|
635
|
+
// to refresh the uri, there is no need to refresh the wallets state
|
|
636
|
+
if (evt?.type === "pairingExpired") {
|
|
637
|
+
debouncedFetchWalletProviders();
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
// if WalletConnect initialization failed, refresh providers
|
|
641
|
+
// (the failed provider will be removed from the list)
|
|
642
|
+
if (evt?.type === "failed") {
|
|
643
|
+
debouncedFetchWalletProviders();
|
|
644
|
+
callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`WalletConnect initialization failed: ${evt.error || "Unknown error"}`, sdkTypes.ZeroXKeyErrorCodes.WALLET_CONNECT_INITIALIZATION_ERROR, evt.error));
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
if (evt?.type === "initialized") {
|
|
648
|
+
// this updates our walletProvider state
|
|
649
|
+
const providers = await debouncedFetchWalletProviders();
|
|
650
|
+
// if we have an active session, we need to restore any possibly connected
|
|
651
|
+
// WalletConnect wallets since its now initialized
|
|
652
|
+
const currentSession = await getSession();
|
|
653
|
+
if (currentSession) {
|
|
654
|
+
const wcProviders = providers?.filter(p => p.interfaceType === core.WalletInterfaceType.WalletConnect);
|
|
655
|
+
const wcWallets = await fetchWallets({
|
|
656
|
+
walletProviders: wcProviders,
|
|
657
|
+
connectedOnly: true
|
|
658
|
+
});
|
|
659
|
+
if (wcWallets.length > 0) {
|
|
660
|
+
setWallets(prev => utils.mergeWalletsWithoutDuplicates(prev, wcWallets));
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
// any other event (disconnect, chain switch, accounts changed)
|
|
666
|
+
// we refresh the wallets state
|
|
667
|
+
await onUpdateState();
|
|
668
|
+
});
|
|
669
|
+
cleanups.push(unsubscribe);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
return () => {
|
|
674
|
+
cleanups.forEach(remove => remove());
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Clears all scheduled session timers (warning + expiry).
|
|
679
|
+
*
|
|
680
|
+
* - Removes all active timers managed by this client.
|
|
681
|
+
* - Useful on re-init or logout to avoid stale timers.
|
|
682
|
+
*
|
|
683
|
+
* @throws {ZeroXKeyError} If an error occurs while clearing the timers.
|
|
684
|
+
*/
|
|
685
|
+
function clearSessionTimeouts(sessionKeys) {
|
|
686
|
+
try {
|
|
687
|
+
if (sessionKeys) {
|
|
688
|
+
timers.clearKeys(expiryTimeoutsRef.current, sessionKeys);
|
|
689
|
+
} else {
|
|
690
|
+
timers.clearAll(expiryTimeoutsRef.current); // clears & deletes everything
|
|
691
|
+
}
|
|
692
|
+
} catch (error) {
|
|
693
|
+
if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
|
|
694
|
+
callbacks?.onError?.(error);
|
|
695
|
+
} else {
|
|
696
|
+
callbacks?.onError?.(new sdkTypes.ZeroXKeyError("Failed to clear session timeouts", sdkTypes.ZeroXKeyErrorCodes.CLEAR_SESSION_TIMEOUTS_ERROR, error));
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* @internal
|
|
702
|
+
* Handles the post-authentication flow.
|
|
703
|
+
*
|
|
704
|
+
* - This function is called after a successful authentication (login or sign-up) via any supported method (Passkey, Wallet, OTP, OAuth).
|
|
705
|
+
* - It fetches the active session and all sessions, updates the session state, and schedules session expiration and warning timeouts.
|
|
706
|
+
* - It also refreshes the user's wallets and profile information to ensure the provider state is up to date.
|
|
707
|
+
* - This function is used internally after all authentication flows to synchronize state and trigger any necessary callbacks.
|
|
708
|
+
*
|
|
709
|
+
* @returns A void promise.
|
|
710
|
+
* @throws {ZeroXKeyError} If the client is not initialized or if there is an error during the process.
|
|
711
|
+
*/
|
|
712
|
+
const handlePostAuth = async params => {
|
|
713
|
+
const {
|
|
714
|
+
method,
|
|
715
|
+
action,
|
|
716
|
+
identifier,
|
|
717
|
+
appProofs
|
|
718
|
+
} = params;
|
|
719
|
+
try {
|
|
720
|
+
const sessionKey = await getActiveSessionKey();
|
|
721
|
+
const session = await getSession({
|
|
722
|
+
...(sessionKey && {
|
|
723
|
+
sessionKey
|
|
724
|
+
})
|
|
725
|
+
});
|
|
726
|
+
if (session && sessionKey) await scheduleSessionExpiration({
|
|
727
|
+
sessionKey,
|
|
728
|
+
expiry: session.expiry
|
|
729
|
+
});
|
|
730
|
+
const allSessions = await client.getAllSessions();
|
|
731
|
+
setSession(session);
|
|
732
|
+
setAllSessions(allSessions);
|
|
733
|
+
await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
|
|
734
|
+
if (masterConfig?.auth?.verifyWalletOnSignup === true && appProofs && appProofs.length > 0 && action === sdkTypes.AuthAction.SIGNUP) {
|
|
735
|
+
// On signup, if we have appProofs, verify them
|
|
736
|
+
await handleVerifyAppProofs({
|
|
737
|
+
appProofs
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
callbacks?.onAuthenticationSuccess?.({
|
|
741
|
+
session,
|
|
742
|
+
method,
|
|
743
|
+
action,
|
|
744
|
+
identifier
|
|
745
|
+
});
|
|
746
|
+
} catch (error) {
|
|
747
|
+
if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
|
|
748
|
+
callbacks?.onError?.(error);
|
|
749
|
+
} else {
|
|
750
|
+
callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to handle post-authentication`, sdkTypes.ZeroXKeyErrorCodes.HANDLE_POST_AUTH_ERROR, error));
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
/**
|
|
755
|
+
* @internal
|
|
756
|
+
* Handles the post-logout flow.
|
|
757
|
+
*
|
|
758
|
+
* - This function is called after a successful logout or session clear.
|
|
759
|
+
* - It clears all scheduled session expiration and warning timeouts associated to the session key to prevent memory leaks.
|
|
760
|
+
* - It resets the session state, removes user data from memory, the logged out session from all sessions state, and clears the wallets list.
|
|
761
|
+
* - This ensures that all sensitive information is removed from the provider state after logout.
|
|
762
|
+
* - Called internally after logout or when all sessions are cleared.
|
|
763
|
+
*
|
|
764
|
+
* @returns void
|
|
765
|
+
* @throws {ZeroXKeyError} If there is an error during the post-logout process.
|
|
766
|
+
*/
|
|
767
|
+
const handlePostLogout = sessionKey => {
|
|
768
|
+
try {
|
|
769
|
+
clearSessionTimeouts(sessionKey ? [sessionKey, `${sessionKey}-warning`] : undefined);
|
|
770
|
+
setAllSessions(prev => {
|
|
771
|
+
if (!prev) return prev;
|
|
772
|
+
if (sessionKey) {
|
|
773
|
+
const next = {
|
|
774
|
+
...prev
|
|
775
|
+
};
|
|
776
|
+
delete next[sessionKey];
|
|
777
|
+
return next;
|
|
778
|
+
}
|
|
779
|
+
return {};
|
|
780
|
+
});
|
|
781
|
+
setSession(undefined);
|
|
782
|
+
setUser(undefined);
|
|
783
|
+
setWallets([]);
|
|
784
|
+
} catch (error) {
|
|
785
|
+
callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize sessions`, sdkTypes.ZeroXKeyErrorCodes.HANDLE_POST_LOGOUT_ERROR, error));
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
const createHttpClient = react.useCallback(params => {
|
|
789
|
+
if (!client) {
|
|
790
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
791
|
+
}
|
|
792
|
+
return client.createHttpClient(params);
|
|
793
|
+
}, [client]);
|
|
794
|
+
const getActiveSessionKey = react.useCallback(async () => {
|
|
795
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
796
|
+
return utils.withZeroXKeyErrorHandling(() => client.getActiveSessionKey(), undefined, callbacks, "Failed to get active session key");
|
|
797
|
+
}, [client, callbacks]);
|
|
798
|
+
const logout = react.useCallback(async params => {
|
|
799
|
+
if (!client) {
|
|
800
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
801
|
+
}
|
|
802
|
+
await utils.withZeroXKeyErrorHandling(async () => {
|
|
803
|
+
// If no sessionKey is provided, we try to get the active one.
|
|
804
|
+
let sessionKey = params?.sessionKey;
|
|
805
|
+
if (!sessionKey) sessionKey = await getActiveSessionKey();
|
|
806
|
+
await client.logout(params);
|
|
807
|
+
// We only handle post logout if the sessionKey is defined since that means we actually logged out of a session.
|
|
808
|
+
if (sessionKey) handlePostLogout(sessionKey);
|
|
809
|
+
}, undefined, callbacks, "Failed to logout");
|
|
810
|
+
return;
|
|
811
|
+
}, [client, callbacks, getActiveSessionKey]);
|
|
812
|
+
const getSession = react.useCallback(async params => {
|
|
813
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
814
|
+
return utils.withZeroXKeyErrorHandling(() => client.getSession(params), undefined, callbacks, "Failed to get session");
|
|
815
|
+
}, [client, callbacks]);
|
|
816
|
+
const getAllSessions = react.useCallback(async () => {
|
|
817
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
818
|
+
return utils.withZeroXKeyErrorHandling(() => client.getAllSessions(), undefined, callbacks, "Failed to get all sessions");
|
|
819
|
+
}, [client, callbacks]);
|
|
820
|
+
const createPasskey = react.useCallback(async params => {
|
|
821
|
+
if (!client) {
|
|
822
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
823
|
+
}
|
|
824
|
+
return utils.withZeroXKeyErrorHandling(() => client.createPasskey({
|
|
825
|
+
...params
|
|
826
|
+
}), undefined, callbacks, "Failed to create passkey");
|
|
827
|
+
}, [client, callbacks]);
|
|
828
|
+
const fetchUser = react.useCallback(async params => {
|
|
829
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
830
|
+
return utils.withZeroXKeyErrorHandling(() => client.fetchUser(params), () => logout(), callbacks, "Failed to fetch user");
|
|
831
|
+
}, [client, callbacks, logout]);
|
|
832
|
+
const fetchWalletProviders = react.useCallback(async chain => {
|
|
833
|
+
if (!client) {
|
|
834
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
835
|
+
}
|
|
836
|
+
return utils.withZeroXKeyErrorHandling(async () => {
|
|
837
|
+
const newProviders = await client.fetchWalletProviders(chain);
|
|
838
|
+
// we update state with the latest providers
|
|
839
|
+
// we keep this state so that initializeWalletProviderListeners() re-runs
|
|
840
|
+
// whenever the list of connected providers changes
|
|
841
|
+
// this ensures we attach disconnect listeners for each connected provider
|
|
842
|
+
setWalletProviders(newProviders);
|
|
843
|
+
return newProviders;
|
|
844
|
+
}, undefined, callbacks, "Failed to fetch wallet providers");
|
|
845
|
+
}, [client, callbacks]);
|
|
846
|
+
const fetchWallets = react.useCallback(async params => {
|
|
847
|
+
if (!client) {
|
|
848
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
849
|
+
}
|
|
850
|
+
return utils.withZeroXKeyErrorHandling(() => client.fetchWallets(params), () => logout(), callbacks, "Failed to fetch wallets");
|
|
851
|
+
}, [client, callbacks, logout]);
|
|
852
|
+
const refreshUser = react.useCallback(async params => {
|
|
853
|
+
const {
|
|
854
|
+
stampWith,
|
|
855
|
+
organizationId,
|
|
856
|
+
userId
|
|
857
|
+
} = params || {};
|
|
858
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
859
|
+
const user = await utils.withZeroXKeyErrorHandling(() => fetchUser({
|
|
860
|
+
stampWith,
|
|
861
|
+
...(organizationId && {
|
|
862
|
+
organizationId
|
|
863
|
+
}),
|
|
864
|
+
...(userId && {
|
|
865
|
+
userId
|
|
866
|
+
})
|
|
867
|
+
}), () => logout(), callbacks, "Failed to refresh user");
|
|
868
|
+
if (user) {
|
|
869
|
+
setUser(user);
|
|
870
|
+
}
|
|
871
|
+
}, [client, callbacks, fetchUser, logout]);
|
|
872
|
+
/**
|
|
873
|
+
* @internal
|
|
874
|
+
* Auto-refresh user only if enabled in config. This is only used internally.
|
|
875
|
+
*
|
|
876
|
+
* @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
|
|
877
|
+
* @param params.userId - user ID to fetch specific user details (defaults to the current session's userId).
|
|
878
|
+
* @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
|
|
879
|
+
* @returns A promise that resolves when the user is refreshed, or does nothing if auto-refresh is disabled
|
|
880
|
+
*/
|
|
881
|
+
const maybeRefreshUser = react.useCallback(async params => {
|
|
882
|
+
if (!masterConfig?.autoRefreshManagedState) return;
|
|
883
|
+
return refreshUser(params);
|
|
884
|
+
}, [masterConfig, refreshUser]);
|
|
885
|
+
const refreshWallets = react.useCallback(async params => {
|
|
886
|
+
const {
|
|
887
|
+
stampWith,
|
|
888
|
+
organizationId,
|
|
889
|
+
userId
|
|
890
|
+
} = params || {};
|
|
891
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
892
|
+
const walletProviders = await utils.withZeroXKeyErrorHandling(() => fetchWalletProviders(), undefined, callbacks, "Failed to refresh wallets");
|
|
893
|
+
const wallets = await utils.withZeroXKeyErrorHandling(() => fetchWallets({
|
|
894
|
+
stampWith,
|
|
895
|
+
walletProviders,
|
|
896
|
+
...(organizationId && {
|
|
897
|
+
organizationId
|
|
898
|
+
}),
|
|
899
|
+
...(userId && {
|
|
900
|
+
userId
|
|
901
|
+
})
|
|
902
|
+
}), () => logout(), callbacks, "Failed to refresh wallets");
|
|
903
|
+
if (wallets) {
|
|
904
|
+
setWallets(wallets);
|
|
905
|
+
}
|
|
906
|
+
return wallets;
|
|
907
|
+
}, [client, callbacks, fetchWalletProviders, fetchWallets, logout]);
|
|
908
|
+
/**
|
|
909
|
+
* @internal
|
|
910
|
+
* Auto-refresh wallets only if enabled in config. This is only used internally.
|
|
911
|
+
*
|
|
912
|
+
* @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
|
|
913
|
+
* @param params.userId - user ID to fetch specific user details (defaults to the current session's userId).
|
|
914
|
+
* @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
|
|
915
|
+
* @returns A promise that resolves to an array of wallets, or an empty array if auto-refresh is disabled
|
|
916
|
+
*/
|
|
917
|
+
const maybeRefreshWallets = react.useCallback(async params => {
|
|
918
|
+
if (!masterConfig?.autoRefreshManagedState) return [];
|
|
919
|
+
return refreshWallets(params);
|
|
920
|
+
}, [masterConfig, refreshWallets]);
|
|
921
|
+
const clearSession = react.useCallback(async params => {
|
|
922
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
923
|
+
await utils.withZeroXKeyErrorHandling(async () => client.clearSession(params), undefined, callbacks, "Failed to clear session");
|
|
924
|
+
const sessionKey = params?.sessionKey ?? (await getActiveSessionKey());
|
|
925
|
+
if (!sessionKey) return;
|
|
926
|
+
if (!params?.sessionKey) {
|
|
927
|
+
setSession(undefined);
|
|
928
|
+
}
|
|
929
|
+
clearSessionTimeouts([sessionKey]);
|
|
930
|
+
// clear only the cleared session from allSessions
|
|
931
|
+
const newAllSessions = {
|
|
932
|
+
...allSessions
|
|
933
|
+
};
|
|
934
|
+
if (newAllSessions) {
|
|
935
|
+
delete newAllSessions[sessionKey];
|
|
936
|
+
}
|
|
937
|
+
setAllSessions(newAllSessions);
|
|
938
|
+
return;
|
|
939
|
+
}, [client, callbacks, getActiveSessionKey, allSessions]);
|
|
940
|
+
/**
|
|
941
|
+
* @internal
|
|
942
|
+
* Schedules a session expiration and warning timer for the given session key.
|
|
943
|
+
*
|
|
944
|
+
* - Sets up two timers: one for warning before expiry and one for actual expiry.
|
|
945
|
+
* - Uses capped timeouts under the hood so delays > 24.8 days are safe (see utils/timers.ts).
|
|
946
|
+
*
|
|
947
|
+
* @param params.sessionKey - The key of the session to schedule expiration for.
|
|
948
|
+
* @param params.expiry - The expiration time in seconds since epoch.
|
|
949
|
+
* @throws {ZeroXKeyError} If an error occurs while scheduling the session expiration.
|
|
950
|
+
*/
|
|
951
|
+
const scheduleSessionExpiration = react.useCallback(async params => {
|
|
952
|
+
const {
|
|
953
|
+
sessionKey,
|
|
954
|
+
expiry
|
|
955
|
+
} = params;
|
|
956
|
+
try {
|
|
957
|
+
const warnKey = `${sessionKey}-warning`;
|
|
958
|
+
// Replace any prior timers for this session
|
|
959
|
+
timers.clearKey(expiryTimeoutsRef.current, sessionKey);
|
|
960
|
+
timers.clearKey(expiryTimeoutsRef.current, warnKey);
|
|
961
|
+
const now = Date.now();
|
|
962
|
+
const expiryMs = expiry * 1000;
|
|
963
|
+
const timeUntilExpiry = expiryMs - now;
|
|
964
|
+
const runRefresh = async () => {
|
|
965
|
+
const activeSession = await getSession();
|
|
966
|
+
if (!activeSession && expiryTimeoutsRef.current[warnKey]) {
|
|
967
|
+
// Keep nudging until session materializes (short 10s timer is fine)
|
|
968
|
+
timers.setTimeoutInMap(expiryTimeoutsRef.current, warnKey, runRefresh, 10_000);
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
const session = await getSession({
|
|
972
|
+
sessionKey
|
|
973
|
+
});
|
|
974
|
+
if (!session) return;
|
|
975
|
+
callbacks?.beforeSessionExpiry?.({
|
|
976
|
+
sessionKey
|
|
977
|
+
});
|
|
978
|
+
if (masterConfig?.auth?.autoRefreshSession) {
|
|
979
|
+
await refreshSession({
|
|
980
|
+
expirationSeconds: session.expirationSeconds,
|
|
981
|
+
sessionKey
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
const expireSession = async () => {
|
|
986
|
+
const expiredSession = await getSession({
|
|
987
|
+
sessionKey
|
|
988
|
+
});
|
|
989
|
+
if (!expiredSession) return;
|
|
990
|
+
callbacks?.onSessionExpired?.({
|
|
991
|
+
sessionKey
|
|
992
|
+
});
|
|
993
|
+
if ((await getActiveSessionKey()) === sessionKey) {
|
|
994
|
+
setSession(undefined);
|
|
995
|
+
}
|
|
996
|
+
setAllSessions(prev => {
|
|
997
|
+
if (!prev) return prev;
|
|
998
|
+
const next = {
|
|
999
|
+
...prev
|
|
1000
|
+
};
|
|
1001
|
+
delete next[sessionKey];
|
|
1002
|
+
return next;
|
|
1003
|
+
});
|
|
1004
|
+
await clearSession({
|
|
1005
|
+
sessionKey
|
|
1006
|
+
});
|
|
1007
|
+
// Remove timers for this session
|
|
1008
|
+
timers.clearKey(expiryTimeoutsRef.current, sessionKey);
|
|
1009
|
+
timers.clearKey(expiryTimeoutsRef.current, warnKey);
|
|
1010
|
+
await logout();
|
|
1011
|
+
};
|
|
1012
|
+
// Already expired → expire immediately
|
|
1013
|
+
if (timeUntilExpiry <= 0) {
|
|
1014
|
+
await expireSession();
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
// Warning timer (if threshold is in the future)
|
|
1018
|
+
const warnAt = expiryMs - utils.SESSION_WARNING_THRESHOLD_MS;
|
|
1019
|
+
if (warnAt <= now) {
|
|
1020
|
+
void runRefresh(); // fire-and-forget is fine
|
|
1021
|
+
} else {
|
|
1022
|
+
timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, warnKey, runRefresh, warnAt - now);
|
|
1023
|
+
}
|
|
1024
|
+
// Actual expiry timer (safe for long delays)
|
|
1025
|
+
timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, sessionKey, expireSession, timeUntilExpiry);
|
|
1026
|
+
} catch (error) {
|
|
1027
|
+
if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
|
|
1028
|
+
callbacks?.onError?.(error);
|
|
1029
|
+
} else {
|
|
1030
|
+
callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to schedule session expiration for ${sessionKey}`, sdkTypes.ZeroXKeyErrorCodes.SCHEDULE_SESSION_EXPIRY_ERROR, error));
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
// Note: `refreshSession()` is intentionally NOT in the dependency array even though
|
|
1035
|
+
// it's called in runRefresh. This is because: `refreshSession()` itself calls `scheduleSessionExpiration()`,
|
|
1036
|
+
// creating a circular dependency that would cause infinite re-renders
|
|
1037
|
+
//
|
|
1038
|
+
// this is fine because `refreshSession()` reference is stable enough for this use case (session
|
|
1039
|
+
// expiration timers are long-lived and don't need to re-subscribe on every `refreshSession()` change)
|
|
1040
|
+
[callbacks, masterConfig, getSession, getActiveSessionKey, clearSession, logout]);
|
|
1041
|
+
const refreshSession = react.useCallback(async params => {
|
|
1042
|
+
if (!client) {
|
|
1043
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1044
|
+
}
|
|
1045
|
+
const activeSessionKey = await client.getActiveSessionKey();
|
|
1046
|
+
if (!activeSessionKey) {
|
|
1047
|
+
throw new sdkTypes.ZeroXKeyError("No active session found.", sdkTypes.ZeroXKeyErrorCodes.NO_SESSION_FOUND);
|
|
1048
|
+
}
|
|
1049
|
+
const sessionKey = params?.sessionKey ?? activeSessionKey;
|
|
1050
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.refreshSession({
|
|
1051
|
+
...params
|
|
1052
|
+
}), () => logout(), callbacks, "Failed to refresh session");
|
|
1053
|
+
const session = await getSession({
|
|
1054
|
+
sessionKey
|
|
1055
|
+
});
|
|
1056
|
+
if (session && sessionKey) {
|
|
1057
|
+
await scheduleSessionExpiration({
|
|
1058
|
+
sessionKey,
|
|
1059
|
+
expiry: session.expiry
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
const allSessions = await getAllSessions();
|
|
1063
|
+
setSession(session);
|
|
1064
|
+
setAllSessions(allSessions);
|
|
1065
|
+
return res;
|
|
1066
|
+
}, [client, callbacks, logout, getSession, scheduleSessionExpiration, getAllSessions]);
|
|
1067
|
+
const loginWithPasskey = react.useCallback(async params => {
|
|
1068
|
+
if (!client) {
|
|
1069
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1070
|
+
}
|
|
1071
|
+
const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
1072
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithPasskey({
|
|
1073
|
+
...params,
|
|
1074
|
+
expirationSeconds
|
|
1075
|
+
}), () => logout(), callbacks, "Failed to login with passkey");
|
|
1076
|
+
if (res) {
|
|
1077
|
+
await handlePostAuth({
|
|
1078
|
+
method: base.AuthMethod.Passkey,
|
|
1079
|
+
action: sdkTypes.AuthAction.LOGIN,
|
|
1080
|
+
identifier: res.credentialId,
|
|
1081
|
+
appProofs: res.appProofs
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
return res;
|
|
1085
|
+
}, [client, callbacks, masterConfig, logout, handlePostAuth]);
|
|
1086
|
+
const signUpWithPasskey = react.useCallback(async params => {
|
|
1087
|
+
if (!client) {
|
|
1088
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1089
|
+
}
|
|
1090
|
+
if (!masterConfig) {
|
|
1091
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1092
|
+
}
|
|
1093
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
1094
|
+
let createSubOrgParams = params?.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.passkeyAuth;
|
|
1095
|
+
params = createSubOrgParams !== undefined ? {
|
|
1096
|
+
...params,
|
|
1097
|
+
createSubOrgParams
|
|
1098
|
+
} : {
|
|
1099
|
+
...params
|
|
1100
|
+
};
|
|
1101
|
+
const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
1102
|
+
const websiteName = window.location.hostname;
|
|
1103
|
+
const timestamp = new Date().toLocaleDateString() + "-" + new Date().toLocaleTimeString([], {
|
|
1104
|
+
hour: "2-digit",
|
|
1105
|
+
minute: "2-digit"
|
|
1106
|
+
});
|
|
1107
|
+
// We allow passkeyName to be passed in thru the provider or thru the params of this function directly.
|
|
1108
|
+
// This is because signUpWithPasskey will create a new passkey using that name.
|
|
1109
|
+
// Any extra authenticators will be created after the first one. (see core implementation)
|
|
1110
|
+
const passkeyName = params?.passkeyDisplayName ?? masterConfig.auth?.createSuborgParams?.passkeyAuth?.passkeyName ?? `${websiteName}-${timestamp}`;
|
|
1111
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithPasskey({
|
|
1112
|
+
...params,
|
|
1113
|
+
passkeyDisplayName: passkeyName,
|
|
1114
|
+
expirationSeconds
|
|
1115
|
+
}), () => logout(), callbacks, "Failed to sign up with passkey");
|
|
1116
|
+
if (res) {
|
|
1117
|
+
await handlePostAuth({
|
|
1118
|
+
method: base.AuthMethod.Passkey,
|
|
1119
|
+
action: sdkTypes.AuthAction.SIGNUP,
|
|
1120
|
+
identifier: res.credentialId,
|
|
1121
|
+
appProofs: res.appProofs
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
return res;
|
|
1125
|
+
}, [client, callbacks, logout, handlePostAuth, masterConfig]);
|
|
1126
|
+
const connectWalletAccount = react.useCallback(async walletProvider => {
|
|
1127
|
+
if (!client) {
|
|
1128
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1129
|
+
}
|
|
1130
|
+
return utils.withZeroXKeyErrorHandling(async () => {
|
|
1131
|
+
const address = await client.connectWalletAccount(walletProvider);
|
|
1132
|
+
let wallets;
|
|
1133
|
+
const s = await getSession();
|
|
1134
|
+
if (s) {
|
|
1135
|
+
// this will update our walletProvider state
|
|
1136
|
+
wallets = await maybeRefreshWallets();
|
|
1137
|
+
} else {
|
|
1138
|
+
wallets = await fetchWallets({
|
|
1139
|
+
connectedOnly: true
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
// we narrow to only connected wallets
|
|
1143
|
+
// because we know the account must come from one of them
|
|
1144
|
+
const connectedWallets = wallets.filter(w => w.source === core.WalletSource.Connected);
|
|
1145
|
+
// find the matching account
|
|
1146
|
+
const matchedAccount = connectedWallets.flatMap(w => w.accounts).find(a => a.address === address);
|
|
1147
|
+
if (!matchedAccount) {
|
|
1148
|
+
throw new sdkTypes.ZeroXKeyError(`No connected wallet account found for address: ${address}`, sdkTypes.ZeroXKeyErrorCodes.NO_WALLET_FOUND);
|
|
1149
|
+
}
|
|
1150
|
+
return matchedAccount;
|
|
1151
|
+
}, () => logout(), callbacks, "Failed to connect wallet account");
|
|
1152
|
+
}, [client, callbacks, getSession, logout, maybeRefreshWallets, fetchWallets]);
|
|
1153
|
+
const disconnectWalletAccount = react.useCallback(async walletProvider => {
|
|
1154
|
+
if (!client) {
|
|
1155
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1156
|
+
}
|
|
1157
|
+
await utils.withZeroXKeyErrorHandling(async () => {
|
|
1158
|
+
await client.disconnectWalletAccount(walletProvider);
|
|
1159
|
+
// no need here to call `maybeRefreshWallets()` because the provider emits a disconnect event which
|
|
1160
|
+
// will trigger a refresh via the listener we set up in `initializeWalletProviderListeners()`
|
|
1161
|
+
}, undefined, callbacks, "Failed to disconnect wallet account");
|
|
1162
|
+
}, [client, callbacks]);
|
|
1163
|
+
const switchWalletAccountChain = react.useCallback(async params => {
|
|
1164
|
+
if (!client) {
|
|
1165
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1166
|
+
}
|
|
1167
|
+
await utils.withZeroXKeyErrorHandling(async () => {
|
|
1168
|
+
await client.switchWalletAccountChain({
|
|
1169
|
+
...params,
|
|
1170
|
+
walletProviders
|
|
1171
|
+
});
|
|
1172
|
+
}, undefined, callbacks, "Failed to switch wallet account chain");
|
|
1173
|
+
}, [client, walletProviders, callbacks]);
|
|
1174
|
+
const buildWalletLoginRequest = react.useCallback(async params => {
|
|
1175
|
+
if (!client) {
|
|
1176
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1177
|
+
}
|
|
1178
|
+
const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
1179
|
+
return await utils.withZeroXKeyErrorHandling(() => client.buildWalletLoginRequest({
|
|
1180
|
+
...params,
|
|
1181
|
+
expirationSeconds
|
|
1182
|
+
}), undefined, callbacks, "Failed to login with wallet");
|
|
1183
|
+
}, [client, callbacks, masterConfig]);
|
|
1184
|
+
const loginWithWallet = react.useCallback(async params => {
|
|
1185
|
+
if (!client) {
|
|
1186
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1187
|
+
}
|
|
1188
|
+
const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
1189
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithWallet({
|
|
1190
|
+
...params,
|
|
1191
|
+
expirationSeconds
|
|
1192
|
+
}), undefined, callbacks, "Failed to login with wallet");
|
|
1193
|
+
if (res) {
|
|
1194
|
+
await handlePostAuth({
|
|
1195
|
+
method: base.AuthMethod.Wallet,
|
|
1196
|
+
action: sdkTypes.AuthAction.LOGIN,
|
|
1197
|
+
identifier: res.address,
|
|
1198
|
+
appProofs: res.appProofs
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
return res;
|
|
1202
|
+
}, [client, callbacks, handlePostAuth, masterConfig]);
|
|
1203
|
+
const signUpWithWallet = react.useCallback(async params => {
|
|
1204
|
+
if (!client) {
|
|
1205
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1206
|
+
}
|
|
1207
|
+
if (!masterConfig) {
|
|
1208
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1209
|
+
}
|
|
1210
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
1211
|
+
let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.walletAuth;
|
|
1212
|
+
params = createSubOrgParams !== undefined ? {
|
|
1213
|
+
...params,
|
|
1214
|
+
createSubOrgParams
|
|
1215
|
+
} : {
|
|
1216
|
+
...params
|
|
1217
|
+
};
|
|
1218
|
+
const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
1219
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithWallet({
|
|
1220
|
+
...params,
|
|
1221
|
+
expirationSeconds
|
|
1222
|
+
}), undefined, callbacks, "Failed to sign up with wallet");
|
|
1223
|
+
if (res) {
|
|
1224
|
+
await handlePostAuth({
|
|
1225
|
+
method: base.AuthMethod.Wallet,
|
|
1226
|
+
action: sdkTypes.AuthAction.SIGNUP,
|
|
1227
|
+
identifier: res.address,
|
|
1228
|
+
appProofs: res.appProofs
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
return res;
|
|
1232
|
+
}, [client, callbacks, handlePostAuth, masterConfig]);
|
|
1233
|
+
const loginOrSignupWithWallet = react.useCallback(async params => {
|
|
1234
|
+
if (!client) {
|
|
1235
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1236
|
+
}
|
|
1237
|
+
if (!masterConfig) {
|
|
1238
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1239
|
+
}
|
|
1240
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
1241
|
+
let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.walletAuth;
|
|
1242
|
+
params = createSubOrgParams !== undefined ? {
|
|
1243
|
+
...params,
|
|
1244
|
+
createSubOrgParams
|
|
1245
|
+
} : {
|
|
1246
|
+
...params
|
|
1247
|
+
};
|
|
1248
|
+
const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
|
|
1249
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.loginOrSignupWithWallet({
|
|
1250
|
+
...params,
|
|
1251
|
+
expirationSeconds
|
|
1252
|
+
}), undefined, callbacks, "Failed to login or sign up with wallet");
|
|
1253
|
+
if (res) {
|
|
1254
|
+
await handlePostAuth({
|
|
1255
|
+
method: base.AuthMethod.Wallet,
|
|
1256
|
+
action: res.action,
|
|
1257
|
+
identifier: res.address,
|
|
1258
|
+
appProofs: res.appProofs
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
return res;
|
|
1262
|
+
}, [client, callbacks, handlePostAuth, masterConfig]);
|
|
1263
|
+
const initOtp = react.useCallback(async params => {
|
|
1264
|
+
if (!client) {
|
|
1265
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1266
|
+
}
|
|
1267
|
+
return utils.withZeroXKeyErrorHandling(() => client.initOtp(params), undefined, callbacks, "Failed to initialize OTP");
|
|
1268
|
+
}, [client, callbacks]);
|
|
1269
|
+
const verifyOtp = react.useCallback(async params => {
|
|
1270
|
+
if (!client) {
|
|
1271
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1272
|
+
}
|
|
1273
|
+
return utils.withZeroXKeyErrorHandling(() => client.verifyOtp(params), undefined, callbacks, "Failed to verify OTP");
|
|
1274
|
+
}, [client, callbacks]);
|
|
1275
|
+
const loginWithOtp = react.useCallback(async params => {
|
|
1276
|
+
if (!client) {
|
|
1277
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1278
|
+
}
|
|
1279
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithOtp(params), undefined, callbacks, "Failed to login with OTP");
|
|
1280
|
+
if (res) {
|
|
1281
|
+
await handlePostAuth({
|
|
1282
|
+
method: base.AuthMethod.Otp,
|
|
1283
|
+
action: sdkTypes.AuthAction.LOGIN,
|
|
1284
|
+
identifier: params.verificationToken,
|
|
1285
|
+
appProofs: res.appProofs
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
return res;
|
|
1289
|
+
}, [client, callbacks, handlePostAuth]);
|
|
1290
|
+
const signUpWithOtp = react.useCallback(async params => {
|
|
1291
|
+
if (!client) {
|
|
1292
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1293
|
+
}
|
|
1294
|
+
if (!masterConfig) {
|
|
1295
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1296
|
+
}
|
|
1297
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
1298
|
+
let createSubOrgParams = params.createSubOrgParams;
|
|
1299
|
+
if (!createSubOrgParams && masterConfig?.auth?.createSuborgParams) {
|
|
1300
|
+
if (params.otpType === core.OtpType.Email) {
|
|
1301
|
+
createSubOrgParams = masterConfig.auth.createSuborgParams.emailOtpAuth;
|
|
1302
|
+
} else if (params.otpType === core.OtpType.Sms) {
|
|
1303
|
+
createSubOrgParams = masterConfig.auth.createSuborgParams.smsOtpAuth;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
params = createSubOrgParams !== undefined ? {
|
|
1307
|
+
...params,
|
|
1308
|
+
createSubOrgParams
|
|
1309
|
+
} : {
|
|
1310
|
+
...params
|
|
1311
|
+
};
|
|
1312
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithOtp(params), undefined, callbacks, "Failed to sign up with OTP");
|
|
1313
|
+
if (res) {
|
|
1314
|
+
await handlePostAuth({
|
|
1315
|
+
method: base.AuthMethod.Otp,
|
|
1316
|
+
action: sdkTypes.AuthAction.SIGNUP,
|
|
1317
|
+
identifier: params.verificationToken,
|
|
1318
|
+
appProofs: res.appProofs
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
return res;
|
|
1322
|
+
}, [client, callbacks, masterConfig, handlePostAuth]);
|
|
1323
|
+
const completeOtp = react.useCallback(async params => {
|
|
1324
|
+
if (!client) {
|
|
1325
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1326
|
+
}
|
|
1327
|
+
if (!masterConfig) {
|
|
1328
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1329
|
+
}
|
|
1330
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
1331
|
+
let createSubOrgParams = params.createSubOrgParams;
|
|
1332
|
+
if (!createSubOrgParams && masterConfig?.auth?.createSuborgParams) {
|
|
1333
|
+
if (params.otpType === core.OtpType.Email) {
|
|
1334
|
+
createSubOrgParams = masterConfig.auth.createSuborgParams.emailOtpAuth;
|
|
1335
|
+
} else if (params.otpType === core.OtpType.Sms) {
|
|
1336
|
+
createSubOrgParams = masterConfig.auth.createSuborgParams.smsOtpAuth;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
params = createSubOrgParams !== undefined ? {
|
|
1340
|
+
...params,
|
|
1341
|
+
createSubOrgParams
|
|
1342
|
+
} : {
|
|
1343
|
+
...params
|
|
1344
|
+
};
|
|
1345
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.completeOtp(params), undefined, callbacks, "Failed to complete OTP");
|
|
1346
|
+
if (res) {
|
|
1347
|
+
await handlePostAuth({
|
|
1348
|
+
method: base.AuthMethod.Otp,
|
|
1349
|
+
action: res.action,
|
|
1350
|
+
identifier: res.verificationToken,
|
|
1351
|
+
appProofs: res.appProofs
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
return res;
|
|
1355
|
+
}, [client, callbacks, handlePostAuth, masterConfig]);
|
|
1356
|
+
const loginWithOauth = react.useCallback(async params => {
|
|
1357
|
+
if (!client) {
|
|
1358
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1359
|
+
}
|
|
1360
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithOauth(params), undefined, callbacks, "Failed to login with OAuth");
|
|
1361
|
+
if (res) {
|
|
1362
|
+
await handlePostAuth({
|
|
1363
|
+
method: base.AuthMethod.Oauth,
|
|
1364
|
+
action: sdkTypes.AuthAction.LOGIN,
|
|
1365
|
+
identifier: params.oidcToken,
|
|
1366
|
+
appProofs: res.appProofs
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1369
|
+
return res;
|
|
1370
|
+
}, [client, callbacks, handlePostAuth]);
|
|
1371
|
+
const signUpWithOauth = react.useCallback(async params => {
|
|
1372
|
+
if (!client) {
|
|
1373
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1374
|
+
}
|
|
1375
|
+
if (!masterConfig) {
|
|
1376
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1377
|
+
}
|
|
1378
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
1379
|
+
let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.oauth;
|
|
1380
|
+
params = createSubOrgParams !== undefined ? {
|
|
1381
|
+
...params,
|
|
1382
|
+
createSubOrgParams
|
|
1383
|
+
} : {
|
|
1384
|
+
...params
|
|
1385
|
+
};
|
|
1386
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithOauth(params), undefined, callbacks, "Failed to sign up with OAuth");
|
|
1387
|
+
if (res) {
|
|
1388
|
+
await handlePostAuth({
|
|
1389
|
+
method: base.AuthMethod.Oauth,
|
|
1390
|
+
action: sdkTypes.AuthAction.SIGNUP,
|
|
1391
|
+
identifier: params.oidcToken,
|
|
1392
|
+
appProofs: res.appProofs
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
return res;
|
|
1396
|
+
}, [client, callbacks, handlePostAuth, masterConfig]);
|
|
1397
|
+
const completeOauth = react.useCallback(async params => {
|
|
1398
|
+
if (!client) {
|
|
1399
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1400
|
+
}
|
|
1401
|
+
if (!masterConfig) {
|
|
1402
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1403
|
+
}
|
|
1404
|
+
// If createSubOrgParams is not provided, use the default from masterConfig
|
|
1405
|
+
const createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.oauth;
|
|
1406
|
+
params = createSubOrgParams !== undefined ? {
|
|
1407
|
+
...params,
|
|
1408
|
+
createSubOrgParams
|
|
1409
|
+
} : {
|
|
1410
|
+
...params
|
|
1411
|
+
};
|
|
1412
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.completeOauth(params), undefined, callbacks, "Failed to complete OAuth");
|
|
1413
|
+
if (res) {
|
|
1414
|
+
await handlePostAuth({
|
|
1415
|
+
method: base.AuthMethod.Oauth,
|
|
1416
|
+
action: res.action,
|
|
1417
|
+
identifier: params.oidcToken,
|
|
1418
|
+
appProofs: res.appProofs
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
return res;
|
|
1422
|
+
}, [client, callbacks, masterConfig, handlePostAuth]);
|
|
1423
|
+
const fetchWalletAccounts = react.useCallback(async params => {
|
|
1424
|
+
if (!client) {
|
|
1425
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1426
|
+
}
|
|
1427
|
+
return utils.withZeroXKeyErrorHandling(() => client.fetchWalletAccounts(params), () => logout(), callbacks, "Failed to fetch wallet accounts");
|
|
1428
|
+
}, [client, callbacks, logout]);
|
|
1429
|
+
const fetchPrivateKeys = react.useCallback(async params => {
|
|
1430
|
+
if (!client) {
|
|
1431
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1432
|
+
}
|
|
1433
|
+
return utils.withZeroXKeyErrorHandling(() => client.fetchPrivateKeys(params), () => logout(), callbacks, "Failed to fetch private keys");
|
|
1434
|
+
}, [client, callbacks, logout]);
|
|
1435
|
+
const signMessage = react.useCallback(async params => {
|
|
1436
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1437
|
+
return utils.withZeroXKeyErrorHandling(() => client.signMessage(params), () => logout(), callbacks, "Failed to sign message");
|
|
1438
|
+
}, [client, callbacks, logout]);
|
|
1439
|
+
const handleSignMessage = react.useCallback(async params => {
|
|
1440
|
+
const {
|
|
1441
|
+
successPageDuration = 2000
|
|
1442
|
+
} = params;
|
|
1443
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1444
|
+
return new Promise((resolve, reject) => {
|
|
1445
|
+
pushPage({
|
|
1446
|
+
key: "Sign message",
|
|
1447
|
+
content: jsxRuntime.jsx(Message.SignMessageModal, {
|
|
1448
|
+
message: params.message,
|
|
1449
|
+
subText: params?.subText,
|
|
1450
|
+
walletAccount: params.walletAccount,
|
|
1451
|
+
stampWith: params.stampWith,
|
|
1452
|
+
successPageDuration: successPageDuration,
|
|
1453
|
+
onSuccess: result => {
|
|
1454
|
+
resolve(result);
|
|
1455
|
+
},
|
|
1456
|
+
onError: error => {
|
|
1457
|
+
reject(error);
|
|
1458
|
+
},
|
|
1459
|
+
...(params?.encoding && {
|
|
1460
|
+
encoding: params.encoding
|
|
1461
|
+
}),
|
|
1462
|
+
...(params?.hashFunction && {
|
|
1463
|
+
hashFunction: params.hashFunction
|
|
1464
|
+
}),
|
|
1465
|
+
...(params?.addEthereumPrefix && {
|
|
1466
|
+
addEthereumPrefix: params.addEthereumPrefix
|
|
1467
|
+
}),
|
|
1468
|
+
...(params?.organizationId && {
|
|
1469
|
+
organizationId: params.organizationId
|
|
1470
|
+
})
|
|
1471
|
+
}),
|
|
1472
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the signing process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
1473
|
+
});
|
|
1474
|
+
});
|
|
1475
|
+
}, [client, callbacks, pushPage]);
|
|
1476
|
+
const signTransaction = react.useCallback(async params => {
|
|
1477
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1478
|
+
return utils.withZeroXKeyErrorHandling(() => client.signTransaction(params), () => logout(), callbacks, "Failed to sign transaction");
|
|
1479
|
+
}, [client, callbacks, logout]);
|
|
1480
|
+
const ethSendTransaction = react.useCallback(async params => {
|
|
1481
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1482
|
+
return utils.withZeroXKeyErrorHandling(() => client.ethSendTransaction(params), () => logout(), callbacks, "Failed to send eth transaction");
|
|
1483
|
+
}, [client, callbacks, logout]);
|
|
1484
|
+
const ethSendErc20Transfer = react.useCallback(async params => {
|
|
1485
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1486
|
+
return utils.withZeroXKeyErrorHandling(() => client.ethSendErc20Transfer(params), () => logout(), callbacks, "Failed to send ERC20 transfer");
|
|
1487
|
+
}, [client, callbacks, logout]);
|
|
1488
|
+
const solSendTransaction = react.useCallback(async params => {
|
|
1489
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1490
|
+
return utils.withZeroXKeyErrorHandling(() => client.solSendTransaction(params), () => logout(), callbacks, "Failed to send sol transaction");
|
|
1491
|
+
}, [client, callbacks, logout]);
|
|
1492
|
+
const signAndSendTransaction = react.useCallback(async params => {
|
|
1493
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1494
|
+
return utils.withZeroXKeyErrorHandling(() => client.signAndSendTransaction(params), () => logout(), callbacks, "Failed to sign and send transaction");
|
|
1495
|
+
}, [client, callbacks, logout]);
|
|
1496
|
+
const pollTransactionStatus = react.useCallback(async params => {
|
|
1497
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1498
|
+
return utils.withZeroXKeyErrorHandling(() => client.pollTransactionStatus(params), () => logout(), callbacks, "Failed to poll transaction status");
|
|
1499
|
+
}, [client, callbacks]);
|
|
1500
|
+
const fetchOrCreateP256ApiKeyUser = react.useCallback(async params => {
|
|
1501
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1502
|
+
return utils.withZeroXKeyErrorHandling(() => client.fetchOrCreateP256ApiKeyUser(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
|
|
1503
|
+
}, [client, callbacks, logout]);
|
|
1504
|
+
const fetchOrCreatePolicies = react.useCallback(async params => {
|
|
1505
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1506
|
+
return utils.withZeroXKeyErrorHandling(() => client.fetchOrCreatePolicies(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
|
|
1507
|
+
}, [client, callbacks, logout]);
|
|
1508
|
+
const updateUserEmail = react.useCallback(async params => {
|
|
1509
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1510
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserEmail(params), () => logout(), callbacks, "Failed to update user email");
|
|
1511
|
+
if (res) await maybeRefreshUser({
|
|
1512
|
+
stampWith: params?.stampWith,
|
|
1513
|
+
...(params?.organizationId && {
|
|
1514
|
+
organizationId: params.organizationId
|
|
1515
|
+
}),
|
|
1516
|
+
...(params?.userId && {
|
|
1517
|
+
userId: params.userId
|
|
1518
|
+
})
|
|
1519
|
+
});
|
|
1520
|
+
return res;
|
|
1521
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1522
|
+
const removeUserEmail = react.useCallback(async params => {
|
|
1523
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1524
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.removeUserEmail(params), () => logout(), callbacks, "Failed to remove user email");
|
|
1525
|
+
if (res) await maybeRefreshUser({
|
|
1526
|
+
stampWith: params?.stampWith,
|
|
1527
|
+
...(params?.organizationId && {
|
|
1528
|
+
organizationId: params.organizationId
|
|
1529
|
+
}),
|
|
1530
|
+
...(params?.userId && {
|
|
1531
|
+
userId: params.userId
|
|
1532
|
+
})
|
|
1533
|
+
});
|
|
1534
|
+
return res;
|
|
1535
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1536
|
+
const updateUserPhoneNumber = react.useCallback(async params => {
|
|
1537
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1538
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserPhoneNumber(params), () => logout(), callbacks, "Failed to update user phone number");
|
|
1539
|
+
if (res) await maybeRefreshUser({
|
|
1540
|
+
stampWith: params?.stampWith,
|
|
1541
|
+
...(params?.organizationId && {
|
|
1542
|
+
organizationId: params.organizationId
|
|
1543
|
+
}),
|
|
1544
|
+
...(params?.userId && {
|
|
1545
|
+
userId: params.userId
|
|
1546
|
+
})
|
|
1547
|
+
});
|
|
1548
|
+
return res;
|
|
1549
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1550
|
+
const removeUserPhoneNumber = react.useCallback(async params => {
|
|
1551
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1552
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.removeUserPhoneNumber(params), () => logout(), callbacks, "Failed to remove user phone number");
|
|
1553
|
+
if (res) await maybeRefreshUser({
|
|
1554
|
+
stampWith: params?.stampWith,
|
|
1555
|
+
...(params?.organizationId && {
|
|
1556
|
+
organizationId: params.organizationId
|
|
1557
|
+
}),
|
|
1558
|
+
...(params?.userId && {
|
|
1559
|
+
userId: params.userId
|
|
1560
|
+
})
|
|
1561
|
+
});
|
|
1562
|
+
return res;
|
|
1563
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1564
|
+
const updateUserName = react.useCallback(async params => {
|
|
1565
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1566
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserName(params), () => logout(), callbacks, "Failed to update user name");
|
|
1567
|
+
if (res) await maybeRefreshUser({
|
|
1568
|
+
stampWith: params?.stampWith,
|
|
1569
|
+
...(params?.organizationId && {
|
|
1570
|
+
organizationId: params.organizationId
|
|
1571
|
+
}),
|
|
1572
|
+
...(params?.userId && {
|
|
1573
|
+
userId: params.userId
|
|
1574
|
+
})
|
|
1575
|
+
});
|
|
1576
|
+
return res;
|
|
1577
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1578
|
+
const addOauthProvider = react.useCallback(async params => {
|
|
1579
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1580
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.addOauthProvider(params), () => logout(), callbacks, "Failed to add OAuth provider");
|
|
1581
|
+
if (res) await maybeRefreshUser({
|
|
1582
|
+
stampWith: params?.stampWith,
|
|
1583
|
+
...(params?.organizationId && {
|
|
1584
|
+
organizationId: params.organizationId
|
|
1585
|
+
}),
|
|
1586
|
+
...(params?.userId && {
|
|
1587
|
+
userId: params.userId
|
|
1588
|
+
})
|
|
1589
|
+
});
|
|
1590
|
+
return res;
|
|
1591
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1592
|
+
const removeOauthProviders = react.useCallback(async params => {
|
|
1593
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1594
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.removeOauthProviders(params), () => logout(), callbacks, "Failed to remove OAuth providers");
|
|
1595
|
+
if (res) await maybeRefreshUser({
|
|
1596
|
+
stampWith: params?.stampWith,
|
|
1597
|
+
...(params?.organizationId && {
|
|
1598
|
+
organizationId: params.organizationId
|
|
1599
|
+
}),
|
|
1600
|
+
...(params?.userId && {
|
|
1601
|
+
userId: params.userId
|
|
1602
|
+
})
|
|
1603
|
+
});
|
|
1604
|
+
return res;
|
|
1605
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1606
|
+
const addPasskey = react.useCallback(async params => {
|
|
1607
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1608
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.addPasskey(params), () => logout(), callbacks, "Failed to add passkey");
|
|
1609
|
+
if (res) await maybeRefreshUser({
|
|
1610
|
+
stampWith: params?.stampWith,
|
|
1611
|
+
...(params?.organizationId && {
|
|
1612
|
+
organizationId: params.organizationId
|
|
1613
|
+
}),
|
|
1614
|
+
...(params?.userId && {
|
|
1615
|
+
userId: params.userId
|
|
1616
|
+
})
|
|
1617
|
+
});
|
|
1618
|
+
return res;
|
|
1619
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1620
|
+
const removePasskeys = react.useCallback(async params => {
|
|
1621
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1622
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.removePasskeys(params), () => logout(), callbacks, "Failed to remove passkeys");
|
|
1623
|
+
if (res) await maybeRefreshUser({
|
|
1624
|
+
stampWith: params?.stampWith,
|
|
1625
|
+
...(params?.organizationId && {
|
|
1626
|
+
organizationId: params.organizationId
|
|
1627
|
+
}),
|
|
1628
|
+
...(params?.userId && {
|
|
1629
|
+
userId: params.userId
|
|
1630
|
+
})
|
|
1631
|
+
});
|
|
1632
|
+
return res;
|
|
1633
|
+
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1634
|
+
const createWallet = react.useCallback(async params => {
|
|
1635
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1636
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.createWallet(params), () => logout(), callbacks, "Failed to create wallet");
|
|
1637
|
+
const s = await getSession();
|
|
1638
|
+
if (res && s) await maybeRefreshWallets({
|
|
1639
|
+
stampWith: params?.stampWith,
|
|
1640
|
+
...(params?.organizationId && {
|
|
1641
|
+
organizationId: params.organizationId
|
|
1642
|
+
})
|
|
1643
|
+
});
|
|
1644
|
+
return res;
|
|
1645
|
+
}, [client, session, callbacks, logout, maybeRefreshWallets, getSession]);
|
|
1646
|
+
const createWalletAccounts = react.useCallback(async params => {
|
|
1647
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1648
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.createWalletAccounts(params), () => logout(), callbacks, "Failed to create wallet accounts");
|
|
1649
|
+
const s = await getSession();
|
|
1650
|
+
if (res && s) await maybeRefreshWallets({
|
|
1651
|
+
stampWith: params?.stampWith,
|
|
1652
|
+
...(params?.organizationId && {
|
|
1653
|
+
organizationId: params.organizationId
|
|
1654
|
+
})
|
|
1655
|
+
});
|
|
1656
|
+
return res;
|
|
1657
|
+
}, [client, session, callbacks, logout, getSession, maybeRefreshWallets]);
|
|
1658
|
+
const exportWallet = react.useCallback(async params => {
|
|
1659
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1660
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.exportWallet(params), () => logout(), callbacks, "Failed to export wallet");
|
|
1661
|
+
const s = await getSession();
|
|
1662
|
+
if (res && s) await maybeRefreshWallets({
|
|
1663
|
+
stampWith: params?.stampWith,
|
|
1664
|
+
...(params?.organizationId && {
|
|
1665
|
+
organizationId: params.organizationId
|
|
1666
|
+
})
|
|
1667
|
+
});
|
|
1668
|
+
return res;
|
|
1669
|
+
}, [client, session, callbacks, logout, getSession, maybeRefreshWallets]);
|
|
1670
|
+
const exportPrivateKey = react.useCallback(async params => {
|
|
1671
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1672
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.exportPrivateKey(params), () => logout(), callbacks, "Failed to export private key");
|
|
1673
|
+
return res;
|
|
1674
|
+
}, [client, callbacks, logout]);
|
|
1675
|
+
const exportWalletAccount = react.useCallback(async params => {
|
|
1676
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1677
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.exportWalletAccount(params), () => logout(), callbacks, "Failed to export wallet accounts");
|
|
1678
|
+
const s = await getSession();
|
|
1679
|
+
if (res && s) await maybeRefreshWallets({
|
|
1680
|
+
stampWith: params?.stampWith,
|
|
1681
|
+
...(params?.organizationId && {
|
|
1682
|
+
organizationId: params.organizationId
|
|
1683
|
+
})
|
|
1684
|
+
});
|
|
1685
|
+
return res;
|
|
1686
|
+
}, [client, callbacks, logout, getSession, maybeRefreshWallets]);
|
|
1687
|
+
const importWallet = react.useCallback(async params => {
|
|
1688
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1689
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.importWallet(params), () => logout(), callbacks, "Failed to import wallet");
|
|
1690
|
+
const s = await getSession();
|
|
1691
|
+
if (res && s) await maybeRefreshWallets({
|
|
1692
|
+
stampWith: params?.stampWith,
|
|
1693
|
+
...(params?.organizationId && {
|
|
1694
|
+
organizationId: params.organizationId
|
|
1695
|
+
}),
|
|
1696
|
+
...(params?.userId && {
|
|
1697
|
+
userId: params.userId
|
|
1698
|
+
})
|
|
1699
|
+
});
|
|
1700
|
+
return res;
|
|
1701
|
+
}, [client, callbacks, logout, getSession, maybeRefreshWallets]);
|
|
1702
|
+
const importPrivateKey = react.useCallback(async params => {
|
|
1703
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1704
|
+
const res = await utils.withZeroXKeyErrorHandling(() => client.importPrivateKey(params), () => logout(), callbacks, "Failed to import private key");
|
|
1705
|
+
return res;
|
|
1706
|
+
}, [client, callbacks, logout]);
|
|
1707
|
+
const deleteSubOrganization = react.useCallback(async params => {
|
|
1708
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1709
|
+
return utils.withZeroXKeyErrorHandling(() => client.deleteSubOrganization(params), () => logout(), callbacks, "Failed to delete sub-organization");
|
|
1710
|
+
}, [client, callbacks, logout]);
|
|
1711
|
+
const storeSession = react.useCallback(async params => {
|
|
1712
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1713
|
+
await utils.withZeroXKeyErrorHandling(() => client.storeSession(params), () => logout(), callbacks, "Failed to store session");
|
|
1714
|
+
const sessionKey = await getActiveSessionKey();
|
|
1715
|
+
const session = await getSession({
|
|
1716
|
+
...(sessionKey && {
|
|
1717
|
+
sessionKey
|
|
1718
|
+
})
|
|
1719
|
+
});
|
|
1720
|
+
if (session && sessionKey) await scheduleSessionExpiration({
|
|
1721
|
+
sessionKey,
|
|
1722
|
+
expiry: session.expiry
|
|
1723
|
+
});
|
|
1724
|
+
const allSessions = await getAllSessions();
|
|
1725
|
+
setSession(session);
|
|
1726
|
+
setAllSessions(allSessions);
|
|
1727
|
+
await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
|
|
1728
|
+
}, [client, callbacks, logout, getActiveSessionKey, getSession, scheduleSessionExpiration, getAllSessions, maybeRefreshWallets, maybeRefreshUser]);
|
|
1729
|
+
const clearAllSessions = react.useCallback(async () => {
|
|
1730
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1731
|
+
setSession(undefined);
|
|
1732
|
+
setAllSessions(undefined);
|
|
1733
|
+
clearSessionTimeouts();
|
|
1734
|
+
return await utils.withZeroXKeyErrorHandling(() => client.clearAllSessions(), () => logout(), callbacks, "Failed to clear all sessions");
|
|
1735
|
+
}, [client, callbacks, logout, clearSessionTimeouts]);
|
|
1736
|
+
const setActiveSession = react.useCallback(async params => {
|
|
1737
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1738
|
+
const session = await utils.withZeroXKeyErrorHandling(() => client.getSession({
|
|
1739
|
+
sessionKey: params.sessionKey
|
|
1740
|
+
}), () => logout(), callbacks, "Failed to get session");
|
|
1741
|
+
const s = await getSession();
|
|
1742
|
+
if (!s) {
|
|
1743
|
+
throw new sdkTypes.ZeroXKeyError("Session not found.", sdkTypes.ZeroXKeyErrorCodes.NOT_FOUND);
|
|
1744
|
+
}
|
|
1745
|
+
await utils.withZeroXKeyErrorHandling(() => client.setActiveSession(params), () => logout(), callbacks, "Failed to set active session");
|
|
1746
|
+
setSession(session);
|
|
1747
|
+
await utils.withZeroXKeyErrorHandling(async () => {
|
|
1748
|
+
await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
|
|
1749
|
+
}, () => logout(), callbacks, "Failed to refresh data after setting active session");
|
|
1750
|
+
return;
|
|
1751
|
+
}, [client, callbacks, logout, getSession, maybeRefreshWallets, maybeRefreshUser]);
|
|
1752
|
+
const clearUnusedKeyPairs = react.useCallback(async () => {
|
|
1753
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1754
|
+
return utils.withZeroXKeyErrorHandling(() => client.clearUnusedKeyPairs(), undefined, callbacks, "Failed to clear unused key pairs");
|
|
1755
|
+
}, [client, callbacks]);
|
|
1756
|
+
const createApiKeyPair = react.useCallback(async params => {
|
|
1757
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1758
|
+
return utils.withZeroXKeyErrorHandling(() => client.createApiKeyPair(params), undefined, callbacks, "Failed to create API key pair");
|
|
1759
|
+
}, [client, callbacks]);
|
|
1760
|
+
const getProxyAuthConfig = react.useCallback(async () => {
|
|
1761
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1762
|
+
return utils.withZeroXKeyErrorHandling(() => client.getProxyAuthConfig(), undefined, callbacks, "Failed to get proxy auth config");
|
|
1763
|
+
}, [client, callbacks]);
|
|
1764
|
+
const fetchBootProofForAppProof = react.useCallback(async params => {
|
|
1765
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1766
|
+
return utils.withZeroXKeyErrorHandling(() => client.fetchBootProofForAppProof(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
|
|
1767
|
+
}, [client, callbacks, logout]);
|
|
1768
|
+
const verifyAppProofs = react.useCallback(async params => {
|
|
1769
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1770
|
+
return utils.withZeroXKeyErrorHandling(() => client.verifyAppProofs(params), () => logout(), callbacks, "Failed to verify app proofs");
|
|
1771
|
+
}, [client, callbacks, logout]);
|
|
1772
|
+
const handleDiscordOauth = react.useCallback(async params => {
|
|
1773
|
+
const {
|
|
1774
|
+
clientId = masterConfig?.auth?.oauthConfig?.discordClientId,
|
|
1775
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1776
|
+
additionalState: additionalParameters
|
|
1777
|
+
} = params || {};
|
|
1778
|
+
const provider = sdkTypes.OAuthProviders.DISCORD;
|
|
1779
|
+
if (!masterConfig) {
|
|
1780
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1781
|
+
}
|
|
1782
|
+
if (!clientId) {
|
|
1783
|
+
throw new sdkTypes.ZeroXKeyError("Discord Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1784
|
+
}
|
|
1785
|
+
if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
|
|
1786
|
+
throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1787
|
+
}
|
|
1788
|
+
const flow = openInPage ? "redirect" : "popup";
|
|
1789
|
+
const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri;
|
|
1790
|
+
// Create key pair and generate nonce
|
|
1791
|
+
const publicKey = await createApiKeyPair();
|
|
1792
|
+
if (!publicKey) {
|
|
1793
|
+
throw new Error("Failed to create public key for OAuth.");
|
|
1794
|
+
}
|
|
1795
|
+
const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
|
|
1796
|
+
// Generate PKCE challenge pair and store verifier
|
|
1797
|
+
const {
|
|
1798
|
+
verifier,
|
|
1799
|
+
codeChallenge
|
|
1800
|
+
} = await pkce.generateChallengePair();
|
|
1801
|
+
storage.storePKCEVerifier(provider, verifier);
|
|
1802
|
+
// Build OAuth URL
|
|
1803
|
+
const authUrl = url.buildOAuthUrl({
|
|
1804
|
+
provider,
|
|
1805
|
+
clientId,
|
|
1806
|
+
redirectUri,
|
|
1807
|
+
publicKey,
|
|
1808
|
+
nonce,
|
|
1809
|
+
flow,
|
|
1810
|
+
codeChallenge,
|
|
1811
|
+
additionalState: additionalParameters
|
|
1812
|
+
});
|
|
1813
|
+
if (openInPage) {
|
|
1814
|
+
// Remainder of logic will occur in completeRedirectOauth
|
|
1815
|
+
return url.redirectToOAuthProvider(authUrl);
|
|
1816
|
+
}
|
|
1817
|
+
// Popup flow
|
|
1818
|
+
const authWindow = url.openOAuthPopup();
|
|
1819
|
+
if (!authWindow) {
|
|
1820
|
+
throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
|
|
1821
|
+
}
|
|
1822
|
+
authWindow.location.href = authUrl;
|
|
1823
|
+
return new Promise((resolve, reject) => {
|
|
1824
|
+
const interval = setInterval(() => {
|
|
1825
|
+
try {
|
|
1826
|
+
if (authWindow.closed) {
|
|
1827
|
+
clearInterval(interval);
|
|
1828
|
+
reject(new Error("Authentication window was closed."));
|
|
1829
|
+
return;
|
|
1830
|
+
}
|
|
1831
|
+
const url$1 = authWindow.location.href || "";
|
|
1832
|
+
if (url$1.startsWith(window.location.origin)) {
|
|
1833
|
+
const result = url.parseOAuthResponse(url$1, provider);
|
|
1834
|
+
if (result) {
|
|
1835
|
+
authWindow.close();
|
|
1836
|
+
clearInterval(interval);
|
|
1837
|
+
completion.completeOAuthPopup({
|
|
1838
|
+
provider,
|
|
1839
|
+
publicKey,
|
|
1840
|
+
result,
|
|
1841
|
+
callbacks,
|
|
1842
|
+
completeOauth,
|
|
1843
|
+
onOauthSuccess: params?.onOauthSuccess,
|
|
1844
|
+
exchangeCodeForToken: async codeVerifier => {
|
|
1845
|
+
const resp = await client?.httpClient.proxyOAuth2Authenticate({
|
|
1846
|
+
provider: "OAUTH2_PROVIDER_DISCORD",
|
|
1847
|
+
authCode: result.authCode,
|
|
1848
|
+
redirectUri,
|
|
1849
|
+
codeVerifier,
|
|
1850
|
+
clientId,
|
|
1851
|
+
nonce
|
|
1852
|
+
});
|
|
1853
|
+
return resp?.oidcToken ?? "";
|
|
1854
|
+
}
|
|
1855
|
+
}).then(() => resolve()).catch(reject);
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
} catch {
|
|
1859
|
+
// ignore cross-origin
|
|
1860
|
+
}
|
|
1861
|
+
}, 500);
|
|
1862
|
+
if (authWindow.closed) {
|
|
1863
|
+
clearInterval(interval);
|
|
1864
|
+
}
|
|
1865
|
+
});
|
|
1866
|
+
}, [client, callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
1867
|
+
const handleXOauth = react.useCallback(async params => {
|
|
1868
|
+
const {
|
|
1869
|
+
clientId = masterConfig?.auth?.oauthConfig?.xClientId,
|
|
1870
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1871
|
+
additionalState: additionalParameters
|
|
1872
|
+
} = params || {};
|
|
1873
|
+
const provider = sdkTypes.OAuthProviders.X;
|
|
1874
|
+
if (!masterConfig) {
|
|
1875
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1876
|
+
}
|
|
1877
|
+
if (!clientId) {
|
|
1878
|
+
throw new sdkTypes.ZeroXKeyError("Twitter Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1879
|
+
}
|
|
1880
|
+
if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
|
|
1881
|
+
throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1882
|
+
}
|
|
1883
|
+
const flow = openInPage ? "redirect" : "popup";
|
|
1884
|
+
const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri;
|
|
1885
|
+
// Create key pair and generate nonce
|
|
1886
|
+
const publicKey = await createApiKeyPair();
|
|
1887
|
+
if (!publicKey) {
|
|
1888
|
+
throw new Error("Failed to create public key for OAuth.");
|
|
1889
|
+
}
|
|
1890
|
+
const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
|
|
1891
|
+
// Generate PKCE challenge pair and store verifier
|
|
1892
|
+
const {
|
|
1893
|
+
verifier,
|
|
1894
|
+
codeChallenge
|
|
1895
|
+
} = await pkce.generateChallengePair();
|
|
1896
|
+
storage.storePKCEVerifier(provider, verifier);
|
|
1897
|
+
// Build OAuth URL
|
|
1898
|
+
const authUrl = url.buildOAuthUrl({
|
|
1899
|
+
provider,
|
|
1900
|
+
clientId,
|
|
1901
|
+
redirectUri,
|
|
1902
|
+
publicKey,
|
|
1903
|
+
nonce,
|
|
1904
|
+
flow,
|
|
1905
|
+
codeChallenge,
|
|
1906
|
+
additionalState: additionalParameters
|
|
1907
|
+
});
|
|
1908
|
+
if (openInPage) {
|
|
1909
|
+
// Remainder of logic will occur in completeRedirectOauth
|
|
1910
|
+
return url.redirectToOAuthProvider(authUrl);
|
|
1911
|
+
}
|
|
1912
|
+
// Popup flow
|
|
1913
|
+
const authWindow = url.openOAuthPopup();
|
|
1914
|
+
if (!authWindow) {
|
|
1915
|
+
throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
|
|
1916
|
+
}
|
|
1917
|
+
authWindow.location.href = authUrl;
|
|
1918
|
+
return new Promise((resolve, reject) => {
|
|
1919
|
+
const interval = setInterval(() => {
|
|
1920
|
+
try {
|
|
1921
|
+
if (authWindow.closed) {
|
|
1922
|
+
clearInterval(interval);
|
|
1923
|
+
reject(new Error("Authentication window was closed."));
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
const url$1 = authWindow.location.href || "";
|
|
1927
|
+
if (url$1.startsWith(window.location.origin)) {
|
|
1928
|
+
const result = url.parseOAuthResponse(url$1, provider);
|
|
1929
|
+
if (result) {
|
|
1930
|
+
authWindow.close();
|
|
1931
|
+
clearInterval(interval);
|
|
1932
|
+
completion.completeOAuthPopup({
|
|
1933
|
+
provider,
|
|
1934
|
+
publicKey,
|
|
1935
|
+
result,
|
|
1936
|
+
callbacks,
|
|
1937
|
+
completeOauth,
|
|
1938
|
+
onOauthSuccess: params?.onOauthSuccess,
|
|
1939
|
+
exchangeCodeForToken: async codeVerifier => {
|
|
1940
|
+
const resp = await client?.httpClient.proxyOAuth2Authenticate({
|
|
1941
|
+
provider: "OAUTH2_PROVIDER_X",
|
|
1942
|
+
authCode: result.authCode,
|
|
1943
|
+
redirectUri,
|
|
1944
|
+
codeVerifier,
|
|
1945
|
+
clientId,
|
|
1946
|
+
nonce
|
|
1947
|
+
});
|
|
1948
|
+
return resp?.oidcToken ?? "";
|
|
1949
|
+
}
|
|
1950
|
+
}).then(() => resolve()).catch(reject);
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
} catch {
|
|
1954
|
+
// ignore cross-origin
|
|
1955
|
+
}
|
|
1956
|
+
}, 500);
|
|
1957
|
+
if (authWindow.closed) {
|
|
1958
|
+
clearInterval(interval);
|
|
1959
|
+
}
|
|
1960
|
+
});
|
|
1961
|
+
}, [client, callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
1962
|
+
const handleGoogleOauth = react.useCallback(async params => {
|
|
1963
|
+
const {
|
|
1964
|
+
clientId = masterConfig?.auth?.oauthConfig?.googleClientId,
|
|
1965
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1966
|
+
additionalState: additionalParameters
|
|
1967
|
+
} = params || {};
|
|
1968
|
+
const provider = sdkTypes.OAuthProviders.GOOGLE;
|
|
1969
|
+
if (!masterConfig) {
|
|
1970
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1971
|
+
}
|
|
1972
|
+
if (!clientId) {
|
|
1973
|
+
throw new sdkTypes.ZeroXKeyError("Google Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1974
|
+
}
|
|
1975
|
+
if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
|
|
1976
|
+
throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
1977
|
+
}
|
|
1978
|
+
const flow = openInPage ? "redirect" : "popup";
|
|
1979
|
+
// Google requires no trailing slash
|
|
1980
|
+
const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri.replace(/\/$/, "");
|
|
1981
|
+
// Create key pair and generate nonce
|
|
1982
|
+
const publicKey = await createApiKeyPair();
|
|
1983
|
+
if (!publicKey) {
|
|
1984
|
+
throw new Error("Failed to create public key for OAuth.");
|
|
1985
|
+
}
|
|
1986
|
+
const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
|
|
1987
|
+
// Build OAuth URL
|
|
1988
|
+
const authUrl = url.buildOAuthUrl({
|
|
1989
|
+
provider,
|
|
1990
|
+
clientId,
|
|
1991
|
+
redirectUri,
|
|
1992
|
+
publicKey,
|
|
1993
|
+
nonce,
|
|
1994
|
+
flow,
|
|
1995
|
+
additionalState: additionalParameters
|
|
1996
|
+
});
|
|
1997
|
+
if (openInPage) {
|
|
1998
|
+
// Remainder of logic will occur in completeRedirectOauth
|
|
1999
|
+
return url.redirectToOAuthProvider(authUrl);
|
|
2000
|
+
}
|
|
2001
|
+
// Popup flow
|
|
2002
|
+
const authWindow = url.openOAuthPopup();
|
|
2003
|
+
if (!authWindow) {
|
|
2004
|
+
throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
|
|
2005
|
+
}
|
|
2006
|
+
authWindow.location.href = authUrl;
|
|
2007
|
+
return new Promise((resolve, reject) => {
|
|
2008
|
+
const interval = setInterval(() => {
|
|
2009
|
+
try {
|
|
2010
|
+
if (authWindow.closed) {
|
|
2011
|
+
clearInterval(interval);
|
|
2012
|
+
reject(new Error("Authentication window was closed."));
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2015
|
+
const url$1 = authWindow.location.href || "";
|
|
2016
|
+
if (url$1.startsWith(window.location.origin)) {
|
|
2017
|
+
const result = url.parseOAuthResponse(url$1, provider);
|
|
2018
|
+
if (result) {
|
|
2019
|
+
authWindow.close();
|
|
2020
|
+
clearInterval(interval);
|
|
2021
|
+
completion.completeOAuthPopup({
|
|
2022
|
+
provider,
|
|
2023
|
+
publicKey,
|
|
2024
|
+
result,
|
|
2025
|
+
callbacks,
|
|
2026
|
+
completeOauth,
|
|
2027
|
+
onOauthSuccess: params?.onOauthSuccess
|
|
2028
|
+
}).then(() => resolve()).catch(reject);
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
} catch {
|
|
2032
|
+
// Ignore cross-origin errors
|
|
2033
|
+
}
|
|
2034
|
+
}, 500);
|
|
2035
|
+
if (authWindow.closed) {
|
|
2036
|
+
clearInterval(interval);
|
|
2037
|
+
}
|
|
2038
|
+
});
|
|
2039
|
+
}, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
2040
|
+
const handleAppleOauth = react.useCallback(async params => {
|
|
2041
|
+
const {
|
|
2042
|
+
clientId = masterConfig?.auth?.oauthConfig?.appleClientId,
|
|
2043
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
2044
|
+
additionalState: additionalParameters
|
|
2045
|
+
} = params || {};
|
|
2046
|
+
const provider = sdkTypes.OAuthProviders.APPLE;
|
|
2047
|
+
if (!masterConfig) {
|
|
2048
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
2049
|
+
}
|
|
2050
|
+
if (!clientId) {
|
|
2051
|
+
throw new sdkTypes.ZeroXKeyError("Apple Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
2052
|
+
}
|
|
2053
|
+
if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
|
|
2054
|
+
throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
2055
|
+
}
|
|
2056
|
+
const flow = openInPage ? "redirect" : "popup";
|
|
2057
|
+
// TODO (Amir): Apple needs the '/' at the end. Maybe we should add it if not there?
|
|
2058
|
+
const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri;
|
|
2059
|
+
// Create key pair and generate nonce
|
|
2060
|
+
const publicKey = await createApiKeyPair();
|
|
2061
|
+
if (!publicKey) {
|
|
2062
|
+
throw new Error("Failed to create public key for OAuth.");
|
|
2063
|
+
}
|
|
2064
|
+
const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
|
|
2065
|
+
// Build OAuth URL
|
|
2066
|
+
const authUrl = url.buildOAuthUrl({
|
|
2067
|
+
provider,
|
|
2068
|
+
clientId,
|
|
2069
|
+
redirectUri,
|
|
2070
|
+
publicKey,
|
|
2071
|
+
nonce,
|
|
2072
|
+
flow,
|
|
2073
|
+
additionalState: additionalParameters
|
|
2074
|
+
});
|
|
2075
|
+
if (openInPage) {
|
|
2076
|
+
// Remainder of logic will occur in completeRedirectOauth
|
|
2077
|
+
return url.redirectToOAuthProvider(authUrl);
|
|
2078
|
+
}
|
|
2079
|
+
// Popup flow
|
|
2080
|
+
const authWindow = url.openOAuthPopup();
|
|
2081
|
+
if (!authWindow) {
|
|
2082
|
+
throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
|
|
2083
|
+
}
|
|
2084
|
+
authWindow.location.href = authUrl;
|
|
2085
|
+
return new Promise((resolve, reject) => {
|
|
2086
|
+
const interval = setInterval(() => {
|
|
2087
|
+
try {
|
|
2088
|
+
if (authWindow.closed) {
|
|
2089
|
+
clearInterval(interval);
|
|
2090
|
+
reject(new Error("Authentication window was closed."));
|
|
2091
|
+
return;
|
|
2092
|
+
}
|
|
2093
|
+
const url$1 = authWindow.location.href || "";
|
|
2094
|
+
if (url$1.startsWith(window.location.origin)) {
|
|
2095
|
+
const result = url.parseOAuthResponse(url$1, provider);
|
|
2096
|
+
if (result) {
|
|
2097
|
+
authWindow.close();
|
|
2098
|
+
clearInterval(interval);
|
|
2099
|
+
completion.completeOAuthPopup({
|
|
2100
|
+
provider,
|
|
2101
|
+
publicKey,
|
|
2102
|
+
result,
|
|
2103
|
+
callbacks,
|
|
2104
|
+
completeOauth,
|
|
2105
|
+
onOauthSuccess: params?.onOauthSuccess
|
|
2106
|
+
}).then(() => resolve()).catch(reject);
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
} catch {
|
|
2110
|
+
// Ignore cross-origin errors
|
|
2111
|
+
}
|
|
2112
|
+
}, 500);
|
|
2113
|
+
if (authWindow.closed) {
|
|
2114
|
+
clearInterval(interval);
|
|
2115
|
+
}
|
|
2116
|
+
});
|
|
2117
|
+
}, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
2118
|
+
const handleFacebookOauth = react.useCallback(async params => {
|
|
2119
|
+
const {
|
|
2120
|
+
clientId = masterConfig?.auth?.oauthConfig?.facebookClientId,
|
|
2121
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
2122
|
+
additionalState: additionalParameters
|
|
2123
|
+
} = params || {};
|
|
2124
|
+
const provider = sdkTypes.OAuthProviders.FACEBOOK;
|
|
2125
|
+
if (!masterConfig) {
|
|
2126
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
2127
|
+
}
|
|
2128
|
+
if (!clientId) {
|
|
2129
|
+
throw new sdkTypes.ZeroXKeyError("Facebook Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
2130
|
+
}
|
|
2131
|
+
if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
|
|
2132
|
+
throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
|
|
2133
|
+
}
|
|
2134
|
+
const flow = openInPage ? "redirect" : "popup";
|
|
2135
|
+
const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri;
|
|
2136
|
+
// Create key pair and generate nonce
|
|
2137
|
+
const publicKey = await createApiKeyPair();
|
|
2138
|
+
if (!publicKey) {
|
|
2139
|
+
throw new Error("Failed to create public key for OAuth.");
|
|
2140
|
+
}
|
|
2141
|
+
const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
|
|
2142
|
+
// Generate PKCE challenge pair and store verifier
|
|
2143
|
+
const {
|
|
2144
|
+
verifier,
|
|
2145
|
+
codeChallenge
|
|
2146
|
+
} = await pkce.generateChallengePair();
|
|
2147
|
+
storage.storePKCEVerifier(provider, verifier);
|
|
2148
|
+
// Build OAuth URL
|
|
2149
|
+
const authUrl = url.buildOAuthUrl({
|
|
2150
|
+
provider,
|
|
2151
|
+
clientId,
|
|
2152
|
+
redirectUri,
|
|
2153
|
+
publicKey,
|
|
2154
|
+
nonce,
|
|
2155
|
+
flow,
|
|
2156
|
+
codeChallenge,
|
|
2157
|
+
additionalState: additionalParameters
|
|
2158
|
+
});
|
|
2159
|
+
if (openInPage) {
|
|
2160
|
+
// Remainder of logic will occur in completeRedirectOauth
|
|
2161
|
+
return url.redirectToOAuthProvider(authUrl);
|
|
2162
|
+
}
|
|
2163
|
+
// Popup flow
|
|
2164
|
+
const authWindow = url.openOAuthPopup();
|
|
2165
|
+
if (!authWindow) {
|
|
2166
|
+
throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
|
|
2167
|
+
}
|
|
2168
|
+
authWindow.location.href = authUrl;
|
|
2169
|
+
return new Promise((resolve, reject) => {
|
|
2170
|
+
const interval = setInterval(() => {
|
|
2171
|
+
try {
|
|
2172
|
+
if (authWindow.closed) {
|
|
2173
|
+
clearInterval(interval);
|
|
2174
|
+
reject(new Error("Authentication window was closed."));
|
|
2175
|
+
return;
|
|
2176
|
+
}
|
|
2177
|
+
const url$1 = authWindow.location.href || "";
|
|
2178
|
+
if (url$1.startsWith(window.location.origin)) {
|
|
2179
|
+
const result = url.parseOAuthResponse(url$1, provider);
|
|
2180
|
+
if (result) {
|
|
2181
|
+
authWindow.close();
|
|
2182
|
+
clearInterval(interval);
|
|
2183
|
+
completion.completeOAuthPopup({
|
|
2184
|
+
provider,
|
|
2185
|
+
publicKey,
|
|
2186
|
+
result,
|
|
2187
|
+
callbacks,
|
|
2188
|
+
completeOauth,
|
|
2189
|
+
onOauthSuccess: params?.onOauthSuccess,
|
|
2190
|
+
exchangeCodeForToken: async codeVerifier => {
|
|
2191
|
+
const tokenData = await pkce.exchangeFacebookCodeForToken(clientId, redirectUri, result.authCode, codeVerifier);
|
|
2192
|
+
return tokenData.id_token;
|
|
2193
|
+
}
|
|
2194
|
+
}).then(() => resolve()).catch(reject);
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
} catch {
|
|
2198
|
+
// Ignore cross-origin errors
|
|
2199
|
+
}
|
|
2200
|
+
}, 500);
|
|
2201
|
+
if (authWindow.closed) {
|
|
2202
|
+
clearInterval(interval);
|
|
2203
|
+
}
|
|
2204
|
+
});
|
|
2205
|
+
}, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
2206
|
+
const handleLogin = react.useCallback(async params => {
|
|
2207
|
+
const logo = masterConfig?.ui?.darkMode ? params?.logoDark ?? masterConfig?.ui?.logoDark : params?.logoLight ?? masterConfig?.ui?.logoLight;
|
|
2208
|
+
pushPage({
|
|
2209
|
+
key: params?.title ?? "Log in or sign up",
|
|
2210
|
+
content: jsxRuntime.jsx(index.AuthComponent, {
|
|
2211
|
+
sessionKey: params?.sessionKey,
|
|
2212
|
+
logo: logo,
|
|
2213
|
+
logoClassName: params?.logoClassName,
|
|
2214
|
+
title: params?.title
|
|
2215
|
+
}),
|
|
2216
|
+
showTitle: false,
|
|
2217
|
+
preventClose: true
|
|
2218
|
+
});
|
|
2219
|
+
}, [pushPage, masterConfig]);
|
|
2220
|
+
const handleExportWallet = react.useCallback(async params => {
|
|
2221
|
+
const {
|
|
2222
|
+
walletId,
|
|
2223
|
+
targetPublicKey,
|
|
2224
|
+
stampWith,
|
|
2225
|
+
organizationId
|
|
2226
|
+
} = params;
|
|
2227
|
+
return new Promise((resolve, reject) => pushPage({
|
|
2228
|
+
key: "Export wallet",
|
|
2229
|
+
content: jsxRuntime.jsx(Export.ExportComponent, {
|
|
2230
|
+
target: walletId,
|
|
2231
|
+
exportType: base.ExportType.Wallet,
|
|
2232
|
+
...(targetPublicKey !== undefined && {
|
|
2233
|
+
targetPublicKey
|
|
2234
|
+
}),
|
|
2235
|
+
...(stampWith !== undefined && {
|
|
2236
|
+
stampWith
|
|
2237
|
+
}),
|
|
2238
|
+
...(organizationId !== undefined && {
|
|
2239
|
+
organizationId
|
|
2240
|
+
}),
|
|
2241
|
+
onSuccess: () => resolve(),
|
|
2242
|
+
onError: error => reject(error)
|
|
2243
|
+
}),
|
|
2244
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the export wallet process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
2245
|
+
}));
|
|
2246
|
+
}, [pushPage]);
|
|
2247
|
+
const handleExportPrivateKey = react.useCallback(async params => {
|
|
2248
|
+
const {
|
|
2249
|
+
privateKeyId,
|
|
2250
|
+
targetPublicKey,
|
|
2251
|
+
keyFormat,
|
|
2252
|
+
stampWith,
|
|
2253
|
+
organizationId
|
|
2254
|
+
} = params;
|
|
2255
|
+
return new Promise((resolve, reject) => pushPage({
|
|
2256
|
+
key: "Export private key",
|
|
2257
|
+
content: jsxRuntime.jsx(Export.ExportComponent, {
|
|
2258
|
+
target: privateKeyId,
|
|
2259
|
+
exportType: base.ExportType.PrivateKey,
|
|
2260
|
+
...(keyFormat !== undefined && {
|
|
2261
|
+
keyFormat
|
|
2262
|
+
}),
|
|
2263
|
+
...(targetPublicKey !== undefined && {
|
|
2264
|
+
targetPublicKey
|
|
2265
|
+
}),
|
|
2266
|
+
...(stampWith !== undefined && {
|
|
2267
|
+
stampWith
|
|
2268
|
+
}),
|
|
2269
|
+
...(organizationId !== undefined && {
|
|
2270
|
+
organizationId
|
|
2271
|
+
}),
|
|
2272
|
+
onSuccess: () => resolve(),
|
|
2273
|
+
onError: error => reject(error)
|
|
2274
|
+
}),
|
|
2275
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the export private key process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
2276
|
+
}));
|
|
2277
|
+
}, [pushPage]);
|
|
2278
|
+
const handleExportWalletAccount = react.useCallback(async params => {
|
|
2279
|
+
const {
|
|
2280
|
+
address,
|
|
2281
|
+
targetPublicKey,
|
|
2282
|
+
keyFormat,
|
|
2283
|
+
stampWith,
|
|
2284
|
+
organizationId
|
|
2285
|
+
} = params;
|
|
2286
|
+
return new Promise((resolve, reject) => pushPage({
|
|
2287
|
+
key: "Export wallet account",
|
|
2288
|
+
content: jsxRuntime.jsx(Export.ExportComponent, {
|
|
2289
|
+
target: address,
|
|
2290
|
+
exportType: base.ExportType.WalletAccount,
|
|
2291
|
+
...(keyFormat !== undefined && {
|
|
2292
|
+
keyFormat
|
|
2293
|
+
}),
|
|
2294
|
+
...(targetPublicKey !== undefined && {
|
|
2295
|
+
targetPublicKey
|
|
2296
|
+
}),
|
|
2297
|
+
...(stampWith !== undefined && {
|
|
2298
|
+
stampWith
|
|
2299
|
+
}),
|
|
2300
|
+
...(organizationId !== undefined && {
|
|
2301
|
+
organizationId
|
|
2302
|
+
}),
|
|
2303
|
+
onSuccess: () => resolve(),
|
|
2304
|
+
onError: error => reject(error)
|
|
2305
|
+
}),
|
|
2306
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the export wallet account process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
2307
|
+
}));
|
|
2308
|
+
}, [pushPage]);
|
|
2309
|
+
const handleImportWallet = react.useCallback(async params => {
|
|
2310
|
+
const {
|
|
2311
|
+
defaultWalletAccounts,
|
|
2312
|
+
successPageDuration = 2000,
|
|
2313
|
+
stampWith,
|
|
2314
|
+
walletName,
|
|
2315
|
+
clearClipboardOnPaste,
|
|
2316
|
+
organizationId,
|
|
2317
|
+
userId
|
|
2318
|
+
} = params || {};
|
|
2319
|
+
try {
|
|
2320
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => pushPage({
|
|
2321
|
+
key: "Import wallet",
|
|
2322
|
+
content: jsxRuntime.jsx(Import.ImportComponent, {
|
|
2323
|
+
importType: base.ImportType.Wallet,
|
|
2324
|
+
onError: error => {
|
|
2325
|
+
reject(error);
|
|
2326
|
+
},
|
|
2327
|
+
onSuccess: walletId => resolve(walletId),
|
|
2328
|
+
...(defaultWalletAccounts !== undefined && {
|
|
2329
|
+
defaultWalletAccounts
|
|
2330
|
+
}),
|
|
2331
|
+
...(successPageDuration !== undefined && {
|
|
2332
|
+
successPageDuration
|
|
2333
|
+
}),
|
|
2334
|
+
...(clearClipboardOnPaste !== undefined && {
|
|
2335
|
+
clearClipboardOnPaste // Note: This is defaulted to true in the IframeStamper
|
|
2336
|
+
}),
|
|
2337
|
+
...(stampWith !== undefined && {
|
|
2338
|
+
stampWith
|
|
2339
|
+
}),
|
|
2340
|
+
...(walletName !== undefined && {
|
|
2341
|
+
name: walletName
|
|
2342
|
+
}),
|
|
2343
|
+
...(organizationId !== undefined && {
|
|
2344
|
+
organizationId
|
|
2345
|
+
}),
|
|
2346
|
+
...(userId !== undefined && {
|
|
2347
|
+
userId
|
|
2348
|
+
})
|
|
2349
|
+
})
|
|
2350
|
+
})), () => logout());
|
|
2351
|
+
} catch (error) {
|
|
2352
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
2353
|
+
throw error;
|
|
2354
|
+
}
|
|
2355
|
+
throw new sdkTypes.ZeroXKeyError("Failed to import wallet.", sdkTypes.ZeroXKeyErrorCodes.IMPORT_WALLET_ERROR, error);
|
|
2356
|
+
}
|
|
2357
|
+
}, [pushPage, logout]);
|
|
2358
|
+
const handleImportPrivateKey = react.useCallback(async params => {
|
|
2359
|
+
const {
|
|
2360
|
+
curve,
|
|
2361
|
+
addressFormats,
|
|
2362
|
+
successPageDuration = 2000,
|
|
2363
|
+
stampWith,
|
|
2364
|
+
keyName,
|
|
2365
|
+
keyFormat,
|
|
2366
|
+
clearClipboardOnPaste,
|
|
2367
|
+
organizationId
|
|
2368
|
+
} = params || {};
|
|
2369
|
+
try {
|
|
2370
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => pushPage({
|
|
2371
|
+
key: "Import private key",
|
|
2372
|
+
content: jsxRuntime.jsx(Import.ImportComponent, {
|
|
2373
|
+
importType: base.ImportType.PrivateKey,
|
|
2374
|
+
curve: curve,
|
|
2375
|
+
addressFormats: addressFormats,
|
|
2376
|
+
keyFormat: keyFormat,
|
|
2377
|
+
onError: error => {
|
|
2378
|
+
reject(error);
|
|
2379
|
+
},
|
|
2380
|
+
onSuccess: privateKeyId => resolve(privateKeyId),
|
|
2381
|
+
...(successPageDuration !== undefined && {
|
|
2382
|
+
successPageDuration
|
|
2383
|
+
}),
|
|
2384
|
+
...(clearClipboardOnPaste !== undefined && {
|
|
2385
|
+
clearClipboardOnPaste // Note: This is defaulted to true in the IframeStamper
|
|
2386
|
+
}),
|
|
2387
|
+
...(stampWith !== undefined && {
|
|
2388
|
+
stampWith
|
|
2389
|
+
}),
|
|
2390
|
+
...(keyName !== undefined && {
|
|
2391
|
+
name: keyName
|
|
2392
|
+
}),
|
|
2393
|
+
...(organizationId !== undefined && {
|
|
2394
|
+
organizationId
|
|
2395
|
+
})
|
|
2396
|
+
})
|
|
2397
|
+
})), () => logout());
|
|
2398
|
+
} catch (error) {
|
|
2399
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
2400
|
+
throw error;
|
|
2401
|
+
}
|
|
2402
|
+
throw new sdkTypes.ZeroXKeyError("Failed to import private key.", sdkTypes.ZeroXKeyErrorCodes.IMPORT_WALLET_ERROR, error);
|
|
2403
|
+
}
|
|
2404
|
+
}, [pushPage, logout]);
|
|
2405
|
+
const handleUpdateUserName = react.useCallback(async params => {
|
|
2406
|
+
const {
|
|
2407
|
+
successPageDuration = 2000,
|
|
2408
|
+
subTitle,
|
|
2409
|
+
title,
|
|
2410
|
+
stampWith
|
|
2411
|
+
} = params || {};
|
|
2412
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2413
|
+
const s = await getSession();
|
|
2414
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
2415
|
+
if (!organizationId) {
|
|
2416
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2417
|
+
}
|
|
2418
|
+
const userId = params?.userId || user?.userId;
|
|
2419
|
+
if (!userId) {
|
|
2420
|
+
throw new sdkTypes.ZeroXKeyError("A user ID is required to update a user name.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2421
|
+
}
|
|
2422
|
+
const onSuccess = () => {
|
|
2423
|
+
if (!successPageDuration) return;
|
|
2424
|
+
pushPage({
|
|
2425
|
+
key: "success",
|
|
2426
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
2427
|
+
text: "User name changed successfully!",
|
|
2428
|
+
duration: successPageDuration,
|
|
2429
|
+
onComplete: () => {
|
|
2430
|
+
closeModal();
|
|
2431
|
+
}
|
|
2432
|
+
}),
|
|
2433
|
+
preventBack: true,
|
|
2434
|
+
showTitle: false
|
|
2435
|
+
});
|
|
2436
|
+
};
|
|
2437
|
+
try {
|
|
2438
|
+
if (!params?.userName && params?.userName !== "") {
|
|
2439
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2440
|
+
pushPage({
|
|
2441
|
+
key: "Update User Name",
|
|
2442
|
+
content: jsxRuntime.jsx(UpdateUserName.UpdateUserName, {
|
|
2443
|
+
onSuccess: userId => {
|
|
2444
|
+
resolve(userId);
|
|
2445
|
+
},
|
|
2446
|
+
onError: error => {
|
|
2447
|
+
reject(error);
|
|
2448
|
+
},
|
|
2449
|
+
successPageDuration: successPageDuration,
|
|
2450
|
+
stampWith: stampWith,
|
|
2451
|
+
...(title !== undefined && {
|
|
2452
|
+
title
|
|
2453
|
+
}),
|
|
2454
|
+
...(subTitle !== undefined && {
|
|
2455
|
+
subTitle
|
|
2456
|
+
}),
|
|
2457
|
+
organizationId: organizationId,
|
|
2458
|
+
userId: userId
|
|
2459
|
+
}),
|
|
2460
|
+
showTitle: false
|
|
2461
|
+
});
|
|
2462
|
+
}), () => logout());
|
|
2463
|
+
} else {
|
|
2464
|
+
const res = await updateUserName({
|
|
2465
|
+
userName: params.userName,
|
|
2466
|
+
userId: params.userId ?? user.userId,
|
|
2467
|
+
stampWith,
|
|
2468
|
+
...(organizationId !== undefined && {
|
|
2469
|
+
organizationId
|
|
2470
|
+
})
|
|
2471
|
+
});
|
|
2472
|
+
onSuccess();
|
|
2473
|
+
return res;
|
|
2474
|
+
}
|
|
2475
|
+
} catch (error) {
|
|
2476
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
2477
|
+
throw error;
|
|
2478
|
+
}
|
|
2479
|
+
throw new sdkTypes.ZeroXKeyError("Failed to update user name.", sdkTypes.ZeroXKeyErrorCodes.UPDATE_USER_NAME_ERROR, error);
|
|
2480
|
+
}
|
|
2481
|
+
}, [client, getSession, user, pushPage, closeModal, updateUserName, logout]);
|
|
2482
|
+
const handleUpdateUserPhoneNumber = react.useCallback(async params => {
|
|
2483
|
+
const {
|
|
2484
|
+
successPageDuration = 2000,
|
|
2485
|
+
subTitle,
|
|
2486
|
+
title,
|
|
2487
|
+
stampWith
|
|
2488
|
+
} = params || {};
|
|
2489
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2490
|
+
if (!masterConfig) {
|
|
2491
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.CONFIG_NOT_INITIALIZED);
|
|
2492
|
+
}
|
|
2493
|
+
if (!masterConfig.auth?.methods?.smsOtpAuthEnabled) {
|
|
2494
|
+
throw new sdkTypes.ZeroXKeyError("SMS OTP authentication is not enabled in the configuration.", sdkTypes.ZeroXKeyErrorCodes.AUTH_METHOD_NOT_ENABLED);
|
|
2495
|
+
}
|
|
2496
|
+
const s = await getSession();
|
|
2497
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
2498
|
+
if (!organizationId) {
|
|
2499
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2500
|
+
}
|
|
2501
|
+
const userId = params?.userId || s?.userId;
|
|
2502
|
+
if (!userId) {
|
|
2503
|
+
throw new sdkTypes.ZeroXKeyError("A user ID is required to update a phone number.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2504
|
+
}
|
|
2505
|
+
const onSuccess = () => {
|
|
2506
|
+
if (!successPageDuration) return;
|
|
2507
|
+
pushPage({
|
|
2508
|
+
key: "success",
|
|
2509
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
2510
|
+
text: "Phone number changed successfully!",
|
|
2511
|
+
duration: successPageDuration,
|
|
2512
|
+
onComplete: () => {
|
|
2513
|
+
closeModal();
|
|
2514
|
+
}
|
|
2515
|
+
}),
|
|
2516
|
+
preventBack: true,
|
|
2517
|
+
showTitle: false
|
|
2518
|
+
});
|
|
2519
|
+
};
|
|
2520
|
+
try {
|
|
2521
|
+
if (!params?.phoneNumber && params?.phoneNumber !== "") {
|
|
2522
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2523
|
+
pushPage({
|
|
2524
|
+
key: "Update Phone Number",
|
|
2525
|
+
content: jsxRuntime.jsx(UpdatePhoneNumber.UpdatePhoneNumber, {
|
|
2526
|
+
successPageDuration: successPageDuration,
|
|
2527
|
+
onSuccess: userId => resolve(userId),
|
|
2528
|
+
onError: error => reject(error),
|
|
2529
|
+
organizationId: organizationId,
|
|
2530
|
+
userId: userId,
|
|
2531
|
+
...(title !== undefined && {
|
|
2532
|
+
title
|
|
2533
|
+
}),
|
|
2534
|
+
...(subTitle !== undefined && {
|
|
2535
|
+
subTitle
|
|
2536
|
+
}),
|
|
2537
|
+
...(stampWith !== undefined && {
|
|
2538
|
+
stampWith
|
|
2539
|
+
})
|
|
2540
|
+
}),
|
|
2541
|
+
showTitle: false
|
|
2542
|
+
});
|
|
2543
|
+
}), () => logout());
|
|
2544
|
+
} else {
|
|
2545
|
+
const {
|
|
2546
|
+
otpId,
|
|
2547
|
+
otpEncryptionTargetBundle
|
|
2548
|
+
} = await initOtp({
|
|
2549
|
+
otpType: core.OtpType.Sms,
|
|
2550
|
+
contact: params.phoneNumber
|
|
2551
|
+
});
|
|
2552
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2553
|
+
pushPage({
|
|
2554
|
+
key: "Update Phone Number",
|
|
2555
|
+
content: jsxRuntime.jsx(OTP.OtpVerification, {
|
|
2556
|
+
otpType: core.OtpType.Sms,
|
|
2557
|
+
contact: params.phoneNumber,
|
|
2558
|
+
otpId: otpId,
|
|
2559
|
+
otpEncryptionTargetBundle: otpEncryptionTargetBundle,
|
|
2560
|
+
otpLength: masterConfig.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
|
|
2561
|
+
alphanumeric: masterConfig.auth?.otpAlphanumeric,
|
|
2562
|
+
onContinue: async otpCode => {
|
|
2563
|
+
try {
|
|
2564
|
+
const {
|
|
2565
|
+
verificationToken
|
|
2566
|
+
} = await verifyOtp({
|
|
2567
|
+
otpId,
|
|
2568
|
+
otpCode,
|
|
2569
|
+
otpEncryptionTargetBundle,
|
|
2570
|
+
contact: params.phoneNumber,
|
|
2571
|
+
otpType: core.OtpType.Sms
|
|
2572
|
+
});
|
|
2573
|
+
const res = await updateUserPhoneNumber({
|
|
2574
|
+
phoneNumber: params.phoneNumber,
|
|
2575
|
+
verificationToken,
|
|
2576
|
+
userId,
|
|
2577
|
+
organizationId,
|
|
2578
|
+
...(stampWith !== undefined && {
|
|
2579
|
+
stampWith
|
|
2580
|
+
})
|
|
2581
|
+
});
|
|
2582
|
+
onSuccess();
|
|
2583
|
+
resolve(res);
|
|
2584
|
+
} catch (error) {
|
|
2585
|
+
reject(error);
|
|
2586
|
+
}
|
|
2587
|
+
},
|
|
2588
|
+
...(!user?.userPhoneNumber && {
|
|
2589
|
+
title: title ?? "Connect a phone number"
|
|
2590
|
+
}),
|
|
2591
|
+
...(subTitle !== undefined && {
|
|
2592
|
+
subTitle
|
|
2593
|
+
}),
|
|
2594
|
+
...(params.formattedPhone && {
|
|
2595
|
+
formattedPhone: params.formattedPhone
|
|
2596
|
+
})
|
|
2597
|
+
}),
|
|
2598
|
+
showTitle: false
|
|
2599
|
+
});
|
|
2600
|
+
}), () => logout(), callbacks, "Failed to update phone number");
|
|
2601
|
+
}
|
|
2602
|
+
} catch (error) {
|
|
2603
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
2604
|
+
throw error;
|
|
2605
|
+
}
|
|
2606
|
+
throw new sdkTypes.ZeroXKeyError("Failed to initialize OTP for sms verification.", sdkTypes.ZeroXKeyErrorCodes.INIT_OTP_ERROR, error);
|
|
2607
|
+
}
|
|
2608
|
+
}, [client, masterConfig, getSession, pushPage, closeModal, logout, initOtp, verifyOtp, updateUserPhoneNumber, user, callbacks]);
|
|
2609
|
+
const handleUpdateUserEmail = react.useCallback(async params => {
|
|
2610
|
+
const {
|
|
2611
|
+
successPageDuration = 2000,
|
|
2612
|
+
subTitle,
|
|
2613
|
+
title,
|
|
2614
|
+
stampWith
|
|
2615
|
+
} = params || {};
|
|
2616
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2617
|
+
const s = await getSession();
|
|
2618
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
2619
|
+
if (!organizationId) {
|
|
2620
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2621
|
+
}
|
|
2622
|
+
const userId = params?.userId || s?.userId;
|
|
2623
|
+
if (!userId) {
|
|
2624
|
+
throw new sdkTypes.ZeroXKeyError("A user ID is required to update an email.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2625
|
+
}
|
|
2626
|
+
const onSuccess = () => {
|
|
2627
|
+
if (!successPageDuration) return;
|
|
2628
|
+
pushPage({
|
|
2629
|
+
key: "success",
|
|
2630
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
2631
|
+
text: "Email changed successfully!",
|
|
2632
|
+
duration: successPageDuration,
|
|
2633
|
+
onComplete: () => {
|
|
2634
|
+
closeModal();
|
|
2635
|
+
}
|
|
2636
|
+
}),
|
|
2637
|
+
preventBack: true,
|
|
2638
|
+
showTitle: false
|
|
2639
|
+
});
|
|
2640
|
+
};
|
|
2641
|
+
try {
|
|
2642
|
+
if (!params?.email && params?.email !== "") {
|
|
2643
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2644
|
+
pushPage({
|
|
2645
|
+
key: "Update Email",
|
|
2646
|
+
content: jsxRuntime.jsx(UpdateEmail.UpdateEmail, {
|
|
2647
|
+
successPageDuration: successPageDuration,
|
|
2648
|
+
onSuccess: userId => {
|
|
2649
|
+
resolve(userId);
|
|
2650
|
+
},
|
|
2651
|
+
onError: error => reject(error),
|
|
2652
|
+
organizationId: organizationId,
|
|
2653
|
+
userId: userId,
|
|
2654
|
+
...(title !== undefined && {
|
|
2655
|
+
title
|
|
2656
|
+
}),
|
|
2657
|
+
...(subTitle !== undefined && {
|
|
2658
|
+
subTitle
|
|
2659
|
+
}),
|
|
2660
|
+
...(stampWith !== undefined && {
|
|
2661
|
+
stampWith
|
|
2662
|
+
})
|
|
2663
|
+
}),
|
|
2664
|
+
showTitle: false
|
|
2665
|
+
});
|
|
2666
|
+
}), () => logout());
|
|
2667
|
+
} else {
|
|
2668
|
+
const {
|
|
2669
|
+
otpId,
|
|
2670
|
+
otpEncryptionTargetBundle
|
|
2671
|
+
} = await initOtp({
|
|
2672
|
+
otpType: core.OtpType.Email,
|
|
2673
|
+
contact: params.email
|
|
2674
|
+
});
|
|
2675
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2676
|
+
pushPage({
|
|
2677
|
+
key: "Update Email",
|
|
2678
|
+
content: jsxRuntime.jsx(OTP.OtpVerification, {
|
|
2679
|
+
otpType: core.OtpType.Email,
|
|
2680
|
+
contact: params.email,
|
|
2681
|
+
otpId: otpId,
|
|
2682
|
+
otpEncryptionTargetBundle: otpEncryptionTargetBundle,
|
|
2683
|
+
otpLength: masterConfig?.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
|
|
2684
|
+
alphanumeric: masterConfig?.auth?.otpAlphanumeric,
|
|
2685
|
+
onContinue: async otpCode => {
|
|
2686
|
+
try {
|
|
2687
|
+
const {
|
|
2688
|
+
verificationToken
|
|
2689
|
+
} = await verifyOtp({
|
|
2690
|
+
otpId,
|
|
2691
|
+
otpCode,
|
|
2692
|
+
otpEncryptionTargetBundle,
|
|
2693
|
+
contact: params.email,
|
|
2694
|
+
otpType: core.OtpType.Email
|
|
2695
|
+
});
|
|
2696
|
+
const res = await updateUserEmail({
|
|
2697
|
+
email: params.email,
|
|
2698
|
+
verificationToken,
|
|
2699
|
+
userId,
|
|
2700
|
+
organizationId,
|
|
2701
|
+
...(stampWith !== undefined && {
|
|
2702
|
+
stampWith
|
|
2703
|
+
})
|
|
2704
|
+
});
|
|
2705
|
+
onSuccess();
|
|
2706
|
+
resolve(res);
|
|
2707
|
+
} catch (error) {
|
|
2708
|
+
reject(error);
|
|
2709
|
+
}
|
|
2710
|
+
},
|
|
2711
|
+
...(!user?.userEmail && {
|
|
2712
|
+
title: title ?? "Connect an email"
|
|
2713
|
+
}),
|
|
2714
|
+
...(subTitle !== undefined && {
|
|
2715
|
+
subTitle
|
|
2716
|
+
})
|
|
2717
|
+
}),
|
|
2718
|
+
showTitle: false
|
|
2719
|
+
});
|
|
2720
|
+
}), () => logout(), callbacks, "Failed to update email");
|
|
2721
|
+
}
|
|
2722
|
+
} catch (error) {
|
|
2723
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
2724
|
+
throw error;
|
|
2725
|
+
}
|
|
2726
|
+
throw new sdkTypes.ZeroXKeyError("Failed to initialize OTP for email verification.", sdkTypes.ZeroXKeyErrorCodes.INIT_OTP_ERROR, error);
|
|
2727
|
+
}
|
|
2728
|
+
}, [client, getSession, pushPage, closeModal, logout, initOtp, masterConfig, verifyOtp, updateUserEmail, user, callbacks]);
|
|
2729
|
+
const handleAddEmail = react.useCallback(async params => {
|
|
2730
|
+
const {
|
|
2731
|
+
successPageDuration = 2000,
|
|
2732
|
+
subTitle,
|
|
2733
|
+
title,
|
|
2734
|
+
stampWith
|
|
2735
|
+
} = params || {};
|
|
2736
|
+
if (!client) {
|
|
2737
|
+
throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2738
|
+
}
|
|
2739
|
+
const s = await getSession();
|
|
2740
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
2741
|
+
if (!organizationId) {
|
|
2742
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2743
|
+
}
|
|
2744
|
+
const userId = params?.userId || s?.userId;
|
|
2745
|
+
if (!userId) {
|
|
2746
|
+
throw new sdkTypes.ZeroXKeyError("A user ID is required to add an email.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2747
|
+
}
|
|
2748
|
+
const onSuccess = () => {
|
|
2749
|
+
if (!successPageDuration) return;
|
|
2750
|
+
pushPage({
|
|
2751
|
+
key: "success",
|
|
2752
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
2753
|
+
text: "Email added successfully!",
|
|
2754
|
+
duration: successPageDuration,
|
|
2755
|
+
onComplete: () => {
|
|
2756
|
+
closeModal();
|
|
2757
|
+
}
|
|
2758
|
+
}),
|
|
2759
|
+
preventBack: true,
|
|
2760
|
+
showTitle: false
|
|
2761
|
+
});
|
|
2762
|
+
};
|
|
2763
|
+
try {
|
|
2764
|
+
if (!params?.email && params?.email !== "") {
|
|
2765
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2766
|
+
pushPage({
|
|
2767
|
+
key: "Add Email",
|
|
2768
|
+
content: jsxRuntime.jsx(UpdateEmail.UpdateEmail, {
|
|
2769
|
+
successPageDuration: successPageDuration,
|
|
2770
|
+
onSuccess: userId => {
|
|
2771
|
+
resolve(userId);
|
|
2772
|
+
},
|
|
2773
|
+
onError: error => reject(error),
|
|
2774
|
+
...(!user?.userEmail ? {
|
|
2775
|
+
title: title ?? "Connect an email"
|
|
2776
|
+
} : {}),
|
|
2777
|
+
...(subTitle !== undefined ? {
|
|
2778
|
+
subTitle
|
|
2779
|
+
} : {}),
|
|
2780
|
+
organizationId: organizationId,
|
|
2781
|
+
userId: userId,
|
|
2782
|
+
stampWith: stampWith
|
|
2783
|
+
}),
|
|
2784
|
+
showTitle: false
|
|
2785
|
+
});
|
|
2786
|
+
}), () => logout());
|
|
2787
|
+
} else {
|
|
2788
|
+
const {
|
|
2789
|
+
otpId,
|
|
2790
|
+
otpEncryptionTargetBundle
|
|
2791
|
+
} = await initOtp({
|
|
2792
|
+
otpType: core.OtpType.Email,
|
|
2793
|
+
contact: params.email
|
|
2794
|
+
});
|
|
2795
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2796
|
+
pushPage({
|
|
2797
|
+
key: "Add Email",
|
|
2798
|
+
content: jsxRuntime.jsx(OTP.OtpVerification, {
|
|
2799
|
+
otpType: core.OtpType.Email,
|
|
2800
|
+
contact: params.email,
|
|
2801
|
+
otpId: otpId,
|
|
2802
|
+
otpEncryptionTargetBundle: otpEncryptionTargetBundle,
|
|
2803
|
+
otpLength: masterConfig?.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
|
|
2804
|
+
alphanumeric: masterConfig?.auth?.otpAlphanumeric,
|
|
2805
|
+
onContinue: async otpCode => {
|
|
2806
|
+
try {
|
|
2807
|
+
const {
|
|
2808
|
+
verificationToken
|
|
2809
|
+
} = await verifyOtp({
|
|
2810
|
+
otpId,
|
|
2811
|
+
otpCode,
|
|
2812
|
+
otpEncryptionTargetBundle,
|
|
2813
|
+
contact: params.email,
|
|
2814
|
+
otpType: core.OtpType.Email
|
|
2815
|
+
});
|
|
2816
|
+
const res = await updateUserEmail({
|
|
2817
|
+
email: params.email,
|
|
2818
|
+
verificationToken,
|
|
2819
|
+
userId,
|
|
2820
|
+
organizationId,
|
|
2821
|
+
stampWith
|
|
2822
|
+
});
|
|
2823
|
+
onSuccess();
|
|
2824
|
+
resolve(res);
|
|
2825
|
+
} catch (error) {
|
|
2826
|
+
reject(error);
|
|
2827
|
+
}
|
|
2828
|
+
},
|
|
2829
|
+
...(!user?.userEmail && {
|
|
2830
|
+
title: title ?? "Connect an email"
|
|
2831
|
+
}),
|
|
2832
|
+
...(subTitle !== undefined && {
|
|
2833
|
+
subTitle
|
|
2834
|
+
})
|
|
2835
|
+
}),
|
|
2836
|
+
showTitle: false
|
|
2837
|
+
});
|
|
2838
|
+
}), () => logout(), callbacks, "Failed to add email");
|
|
2839
|
+
}
|
|
2840
|
+
} catch (error) {
|
|
2841
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
2842
|
+
throw error;
|
|
2843
|
+
}
|
|
2844
|
+
throw new sdkTypes.ZeroXKeyError("Failed to initialize OTP for email verification.", sdkTypes.ZeroXKeyErrorCodes.INIT_OTP_ERROR, error);
|
|
2845
|
+
}
|
|
2846
|
+
}, [client, getSession, pushPage, closeModal, user, logout, initOtp, masterConfig, verifyOtp, updateUserEmail, callbacks]);
|
|
2847
|
+
const handleAddPhoneNumber = react.useCallback(async params => {
|
|
2848
|
+
const {
|
|
2849
|
+
successPageDuration = 2000,
|
|
2850
|
+
subTitle,
|
|
2851
|
+
title,
|
|
2852
|
+
stampWith
|
|
2853
|
+
} = params || {};
|
|
2854
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2855
|
+
if (!masterConfig) {
|
|
2856
|
+
throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.CONFIG_NOT_INITIALIZED);
|
|
2857
|
+
}
|
|
2858
|
+
if (!masterConfig.auth?.methods?.smsOtpAuthEnabled) {
|
|
2859
|
+
throw new sdkTypes.ZeroXKeyError("SMS OTP authentication is not enabled in the configuration.", sdkTypes.ZeroXKeyErrorCodes.AUTH_METHOD_NOT_ENABLED);
|
|
2860
|
+
}
|
|
2861
|
+
const s = await getSession();
|
|
2862
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
2863
|
+
if (!organizationId) {
|
|
2864
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2865
|
+
}
|
|
2866
|
+
const userId = params?.userId || s?.userId;
|
|
2867
|
+
if (!userId) {
|
|
2868
|
+
throw new sdkTypes.ZeroXKeyError("A user ID is required to add a phone number.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2869
|
+
}
|
|
2870
|
+
const onSuccess = () => {
|
|
2871
|
+
if (!successPageDuration) return;
|
|
2872
|
+
pushPage({
|
|
2873
|
+
key: "success",
|
|
2874
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
2875
|
+
text: "Phone number updated successfully!",
|
|
2876
|
+
duration: successPageDuration,
|
|
2877
|
+
onComplete: () => {
|
|
2878
|
+
closeModal();
|
|
2879
|
+
}
|
|
2880
|
+
}),
|
|
2881
|
+
preventBack: true,
|
|
2882
|
+
showTitle: false
|
|
2883
|
+
});
|
|
2884
|
+
};
|
|
2885
|
+
try {
|
|
2886
|
+
if (!params?.phoneNumber && params?.phoneNumber !== "") {
|
|
2887
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2888
|
+
pushPage({
|
|
2889
|
+
key: "Add Phone Number",
|
|
2890
|
+
content: jsxRuntime.jsx(UpdatePhoneNumber.UpdatePhoneNumber, {
|
|
2891
|
+
successPageDuration: successPageDuration,
|
|
2892
|
+
onSuccess: userId => {
|
|
2893
|
+
resolve(userId);
|
|
2894
|
+
},
|
|
2895
|
+
onError: error => {
|
|
2896
|
+
reject(error);
|
|
2897
|
+
},
|
|
2898
|
+
...(!user?.userPhoneNumber && {
|
|
2899
|
+
title: title ?? "Connect a phone number"
|
|
2900
|
+
}),
|
|
2901
|
+
...(subTitle !== undefined && {
|
|
2902
|
+
subTitle
|
|
2903
|
+
}),
|
|
2904
|
+
organizationId: organizationId,
|
|
2905
|
+
userId: userId,
|
|
2906
|
+
stampWith: stampWith
|
|
2907
|
+
}),
|
|
2908
|
+
showTitle: false
|
|
2909
|
+
});
|
|
2910
|
+
}), () => logout(), callbacks, "Failed to add phone number");
|
|
2911
|
+
} else {
|
|
2912
|
+
const {
|
|
2913
|
+
otpId,
|
|
2914
|
+
otpEncryptionTargetBundle
|
|
2915
|
+
} = await initOtp({
|
|
2916
|
+
otpType: core.OtpType.Sms,
|
|
2917
|
+
contact: params.phoneNumber
|
|
2918
|
+
});
|
|
2919
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2920
|
+
pushPage({
|
|
2921
|
+
key: "Add Phone Number",
|
|
2922
|
+
content: jsxRuntime.jsx(OTP.OtpVerification, {
|
|
2923
|
+
otpType: core.OtpType.Sms,
|
|
2924
|
+
contact: params.phoneNumber,
|
|
2925
|
+
otpId: otpId,
|
|
2926
|
+
otpEncryptionTargetBundle: otpEncryptionTargetBundle,
|
|
2927
|
+
otpLength: masterConfig.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
|
|
2928
|
+
alphanumeric: masterConfig?.auth?.otpAlphanumeric,
|
|
2929
|
+
onContinue: async otpCode => {
|
|
2930
|
+
try {
|
|
2931
|
+
const {
|
|
2932
|
+
verificationToken
|
|
2933
|
+
} = await verifyOtp({
|
|
2934
|
+
otpId,
|
|
2935
|
+
otpCode,
|
|
2936
|
+
otpEncryptionTargetBundle,
|
|
2937
|
+
contact: params.phoneNumber,
|
|
2938
|
+
otpType: core.OtpType.Sms
|
|
2939
|
+
});
|
|
2940
|
+
const res = await updateUserPhoneNumber({
|
|
2941
|
+
phoneNumber: params.phoneNumber,
|
|
2942
|
+
verificationToken,
|
|
2943
|
+
userId,
|
|
2944
|
+
organizationId,
|
|
2945
|
+
stampWith
|
|
2946
|
+
});
|
|
2947
|
+
onSuccess();
|
|
2948
|
+
resolve(res);
|
|
2949
|
+
} catch (error) {
|
|
2950
|
+
reject(error);
|
|
2951
|
+
}
|
|
2952
|
+
},
|
|
2953
|
+
...(!user?.userPhoneNumber && {
|
|
2954
|
+
title: title ?? "Connect a phone number"
|
|
2955
|
+
}),
|
|
2956
|
+
...(subTitle !== undefined && {
|
|
2957
|
+
subTitle
|
|
2958
|
+
}),
|
|
2959
|
+
...(params.formattedPhone && {
|
|
2960
|
+
formattedPhone: params.formattedPhone
|
|
2961
|
+
})
|
|
2962
|
+
}),
|
|
2963
|
+
showTitle: false
|
|
2964
|
+
});
|
|
2965
|
+
}), () => logout(), callbacks, "Failed to add phone number");
|
|
2966
|
+
}
|
|
2967
|
+
} catch (error) {
|
|
2968
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
2969
|
+
throw error;
|
|
2970
|
+
}
|
|
2971
|
+
throw new sdkTypes.ZeroXKeyError("Failed to initialize OTP for sms verification.", sdkTypes.ZeroXKeyErrorCodes.INIT_OTP_ERROR, error);
|
|
2972
|
+
}
|
|
2973
|
+
}, [client, masterConfig, getSession, pushPage, closeModal, user, logout, callbacks, initOtp, verifyOtp, updateUserPhoneNumber]);
|
|
2974
|
+
const handleRemovePasskey = react.useCallback(async params => {
|
|
2975
|
+
const {
|
|
2976
|
+
authenticatorId,
|
|
2977
|
+
successPageDuration = 2000,
|
|
2978
|
+
subTitle,
|
|
2979
|
+
title,
|
|
2980
|
+
stampWith,
|
|
2981
|
+
userId
|
|
2982
|
+
} = params;
|
|
2983
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
2984
|
+
const s = await getSession();
|
|
2985
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
2986
|
+
if (!organizationId) {
|
|
2987
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
2988
|
+
}
|
|
2989
|
+
return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
|
|
2990
|
+
pushPage({
|
|
2991
|
+
key: "Remove Passkey",
|
|
2992
|
+
content: jsxRuntime.jsx(RemovePasskey.RemovePasskey, {
|
|
2993
|
+
authenticatorId: authenticatorId,
|
|
2994
|
+
successPageDuration: successPageDuration,
|
|
2995
|
+
onSuccess: authenticatorIds => {
|
|
2996
|
+
resolve(authenticatorIds);
|
|
2997
|
+
},
|
|
2998
|
+
onError: error => {
|
|
2999
|
+
reject(error);
|
|
3000
|
+
},
|
|
3001
|
+
stampWith: stampWith,
|
|
3002
|
+
...(userId && {
|
|
3003
|
+
userId
|
|
3004
|
+
}),
|
|
3005
|
+
...(title !== undefined && {
|
|
3006
|
+
title
|
|
3007
|
+
}),
|
|
3008
|
+
...(subTitle !== undefined && {
|
|
3009
|
+
subTitle
|
|
3010
|
+
}),
|
|
3011
|
+
...(organizationId !== undefined && {
|
|
3012
|
+
organizationId
|
|
3013
|
+
})
|
|
3014
|
+
}),
|
|
3015
|
+
showTitle: false,
|
|
3016
|
+
preventBack: true
|
|
3017
|
+
});
|
|
3018
|
+
}), () => logout(), callbacks, "Failed to remove passkey");
|
|
3019
|
+
}, [client, getSession, pushPage, logout, callbacks]);
|
|
3020
|
+
const handleAddPasskey = react.useCallback(async params => {
|
|
3021
|
+
const {
|
|
3022
|
+
name,
|
|
3023
|
+
displayName,
|
|
3024
|
+
successPageDuration = 2000,
|
|
3025
|
+
stampWith
|
|
3026
|
+
} = params || {};
|
|
3027
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
3028
|
+
const s = await getSession();
|
|
3029
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
3030
|
+
if (!organizationId) {
|
|
3031
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3032
|
+
}
|
|
3033
|
+
const userId = params?.userId || s?.userId;
|
|
3034
|
+
if (!userId) {
|
|
3035
|
+
throw new sdkTypes.ZeroXKeyError("A user ID or a valid session is required to add a passkey.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3036
|
+
}
|
|
3037
|
+
try {
|
|
3038
|
+
const resPromise = addPasskey({
|
|
3039
|
+
...(name && {
|
|
3040
|
+
name
|
|
3041
|
+
}),
|
|
3042
|
+
...(displayName && {
|
|
3043
|
+
displayName
|
|
3044
|
+
}),
|
|
3045
|
+
userId,
|
|
3046
|
+
stampWith,
|
|
3047
|
+
...(organizationId && {
|
|
3048
|
+
organizationId
|
|
3049
|
+
})
|
|
3050
|
+
});
|
|
3051
|
+
resPromise.then(() => {
|
|
3052
|
+
pushPage({
|
|
3053
|
+
key: "Passkey Added",
|
|
3054
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
3055
|
+
text: "Successfully added passkey!",
|
|
3056
|
+
duration: successPageDuration,
|
|
3057
|
+
onComplete: () => {
|
|
3058
|
+
closeModal();
|
|
3059
|
+
}
|
|
3060
|
+
}),
|
|
3061
|
+
preventBack: true,
|
|
3062
|
+
showTitle: false
|
|
3063
|
+
});
|
|
3064
|
+
});
|
|
3065
|
+
return await resPromise;
|
|
3066
|
+
} catch (error) {
|
|
3067
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
3068
|
+
throw error;
|
|
3069
|
+
}
|
|
3070
|
+
throw new sdkTypes.ZeroXKeyError("Failed to add passkey in handler.", sdkTypes.ZeroXKeyErrorCodes.ADD_PASSKEY_ERROR, error);
|
|
3071
|
+
}
|
|
3072
|
+
}, [client, getSession, addPasskey, pushPage, closeModal]);
|
|
3073
|
+
const handleRemoveOauthProvider = react.useCallback(async params => {
|
|
3074
|
+
const {
|
|
3075
|
+
providerId,
|
|
3076
|
+
successPageDuration = 2000,
|
|
3077
|
+
subTitle,
|
|
3078
|
+
title,
|
|
3079
|
+
stampWith
|
|
3080
|
+
} = params;
|
|
3081
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
3082
|
+
const s = await getSession();
|
|
3083
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
3084
|
+
if (!organizationId) {
|
|
3085
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3086
|
+
}
|
|
3087
|
+
try {
|
|
3088
|
+
return new Promise((resolve, reject) => {
|
|
3089
|
+
pushPage({
|
|
3090
|
+
key: "Remove OAuth Provider",
|
|
3091
|
+
content: jsxRuntime.jsx(RemoveOAuthProvider.RemoveOAuthProvider, {
|
|
3092
|
+
providerId: providerId,
|
|
3093
|
+
stampWith: stampWith,
|
|
3094
|
+
successPageDuration: successPageDuration,
|
|
3095
|
+
onSuccess: providerIds => {
|
|
3096
|
+
resolve(providerIds);
|
|
3097
|
+
},
|
|
3098
|
+
onError: error => {
|
|
3099
|
+
reject(error);
|
|
3100
|
+
},
|
|
3101
|
+
...(title !== undefined && {
|
|
3102
|
+
title
|
|
3103
|
+
}),
|
|
3104
|
+
...(subTitle !== undefined && {
|
|
3105
|
+
subTitle
|
|
3106
|
+
}),
|
|
3107
|
+
...(organizationId !== undefined && {
|
|
3108
|
+
organizationId
|
|
3109
|
+
})
|
|
3110
|
+
}),
|
|
3111
|
+
showTitle: false,
|
|
3112
|
+
preventBack: true,
|
|
3113
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the remove OAuth provider process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
3114
|
+
});
|
|
3115
|
+
});
|
|
3116
|
+
} catch (error) {
|
|
3117
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
3118
|
+
throw error;
|
|
3119
|
+
}
|
|
3120
|
+
throw new sdkTypes.ZeroXKeyError("Failed to remove OAuth provider in handler.", sdkTypes.ZeroXKeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR, error);
|
|
3121
|
+
}
|
|
3122
|
+
}, [client, getSession, pushPage]);
|
|
3123
|
+
const handleAddOauthProvider = react.useCallback(async params => {
|
|
3124
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
3125
|
+
const {
|
|
3126
|
+
providerName,
|
|
3127
|
+
stampWith,
|
|
3128
|
+
successPageDuration = 2000,
|
|
3129
|
+
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false
|
|
3130
|
+
} = params;
|
|
3131
|
+
const s = await getSession();
|
|
3132
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
3133
|
+
if (!organizationId) {
|
|
3134
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3135
|
+
}
|
|
3136
|
+
const userId = params?.userId || s?.userId;
|
|
3137
|
+
if (!userId) {
|
|
3138
|
+
throw new sdkTypes.ZeroXKeyError("A user ID is required to add an OAuth provider.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3139
|
+
}
|
|
3140
|
+
return new Promise(async (resolve, reject) => {
|
|
3141
|
+
try {
|
|
3142
|
+
const onOauthSuccess = async params => {
|
|
3143
|
+
await addOauthProvider({
|
|
3144
|
+
providerName: params.providerName,
|
|
3145
|
+
oidcToken: params.oidcToken,
|
|
3146
|
+
stampWith,
|
|
3147
|
+
organizationId,
|
|
3148
|
+
userId
|
|
3149
|
+
});
|
|
3150
|
+
resolve();
|
|
3151
|
+
pushPage({
|
|
3152
|
+
key: "OAuth Provider Added",
|
|
3153
|
+
content: jsxRuntime.jsx(Success.SuccessPage, {
|
|
3154
|
+
text: `Successfully added ${params.providerName} OAuth provider!`,
|
|
3155
|
+
duration: successPageDuration,
|
|
3156
|
+
onComplete: () => {
|
|
3157
|
+
closeModal();
|
|
3158
|
+
}
|
|
3159
|
+
}),
|
|
3160
|
+
preventBack: true,
|
|
3161
|
+
showTitle: false
|
|
3162
|
+
});
|
|
3163
|
+
};
|
|
3164
|
+
if (openInPage) {
|
|
3165
|
+
storage.storeOAuthAddProviderMetadata({
|
|
3166
|
+
organizationId,
|
|
3167
|
+
userId,
|
|
3168
|
+
...(stampWith && {
|
|
3169
|
+
stampWith: stampWith
|
|
3170
|
+
}),
|
|
3171
|
+
successPageDuration
|
|
3172
|
+
});
|
|
3173
|
+
}
|
|
3174
|
+
const additionalState = openInPage ? {
|
|
3175
|
+
oauthIntent: storage.OAUTH_INTENT_ADD_PROVIDER,
|
|
3176
|
+
...(successPageDuration > 0 && {
|
|
3177
|
+
openModal: "true"
|
|
3178
|
+
})
|
|
3179
|
+
} : undefined;
|
|
3180
|
+
switch (providerName) {
|
|
3181
|
+
case sdkTypes.OAuthProviders.DISCORD:
|
|
3182
|
+
{
|
|
3183
|
+
return await handleDiscordOauth({
|
|
3184
|
+
openInPage,
|
|
3185
|
+
...(additionalState && {
|
|
3186
|
+
additionalState
|
|
3187
|
+
}),
|
|
3188
|
+
...(!openInPage && {
|
|
3189
|
+
onOauthSuccess
|
|
3190
|
+
})
|
|
3191
|
+
});
|
|
3192
|
+
}
|
|
3193
|
+
case sdkTypes.OAuthProviders.X:
|
|
3194
|
+
{
|
|
3195
|
+
return await handleXOauth({
|
|
3196
|
+
openInPage,
|
|
3197
|
+
...(additionalState && {
|
|
3198
|
+
additionalState
|
|
3199
|
+
}),
|
|
3200
|
+
...(!openInPage && {
|
|
3201
|
+
onOauthSuccess
|
|
3202
|
+
})
|
|
3203
|
+
});
|
|
3204
|
+
}
|
|
3205
|
+
case sdkTypes.OAuthProviders.GOOGLE:
|
|
3206
|
+
{
|
|
3207
|
+
return await handleGoogleOauth({
|
|
3208
|
+
openInPage,
|
|
3209
|
+
...(additionalState && {
|
|
3210
|
+
additionalState
|
|
3211
|
+
}),
|
|
3212
|
+
...(!openInPage && {
|
|
3213
|
+
onOauthSuccess
|
|
3214
|
+
})
|
|
3215
|
+
});
|
|
3216
|
+
}
|
|
3217
|
+
case sdkTypes.OAuthProviders.APPLE:
|
|
3218
|
+
{
|
|
3219
|
+
return await handleAppleOauth({
|
|
3220
|
+
openInPage,
|
|
3221
|
+
...(additionalState && {
|
|
3222
|
+
additionalState
|
|
3223
|
+
}),
|
|
3224
|
+
...(!openInPage && {
|
|
3225
|
+
onOauthSuccess
|
|
3226
|
+
})
|
|
3227
|
+
});
|
|
3228
|
+
}
|
|
3229
|
+
case sdkTypes.OAuthProviders.FACEBOOK:
|
|
3230
|
+
{
|
|
3231
|
+
return await handleFacebookOauth({
|
|
3232
|
+
openInPage,
|
|
3233
|
+
...(additionalState && {
|
|
3234
|
+
additionalState
|
|
3235
|
+
}),
|
|
3236
|
+
...(!openInPage && {
|
|
3237
|
+
onOauthSuccess
|
|
3238
|
+
})
|
|
3239
|
+
});
|
|
3240
|
+
}
|
|
3241
|
+
default:
|
|
3242
|
+
{
|
|
3243
|
+
throw new sdkTypes.ZeroXKeyError(`Unsupported OAuth provider: ${providerName}`, sdkTypes.ZeroXKeyErrorCodes.NOT_FOUND);
|
|
3244
|
+
}
|
|
3245
|
+
}
|
|
3246
|
+
} catch (error) {
|
|
3247
|
+
reject(error);
|
|
3248
|
+
}
|
|
3249
|
+
});
|
|
3250
|
+
}, [client, getSession, addOauthProvider, pushPage, closeModal, handleDiscordOauth, handleXOauth, handleGoogleOauth, handleAppleOauth, handleFacebookOauth]);
|
|
3251
|
+
const handleConnectExternalWallet = react.useCallback(async params => {
|
|
3252
|
+
const {
|
|
3253
|
+
successPageDuration = 2000
|
|
3254
|
+
} = params || {};
|
|
3255
|
+
if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
3256
|
+
if (!masterConfig?.walletConfig?.features?.connecting) {
|
|
3257
|
+
throw new sdkTypes.ZeroXKeyError("Wallet connecting is not enabled.", sdkTypes.ZeroXKeyErrorCodes.FEATURE_NOT_ENABLED);
|
|
3258
|
+
}
|
|
3259
|
+
return new Promise((resolve, reject) => {
|
|
3260
|
+
pushPage({
|
|
3261
|
+
key: "Connect wallet",
|
|
3262
|
+
content: jsxRuntime.jsx(ConnectWallet.ConnectWalletModal, {
|
|
3263
|
+
successPageDuration: successPageDuration,
|
|
3264
|
+
onSuccess: (type, account) => {
|
|
3265
|
+
resolve({
|
|
3266
|
+
type,
|
|
3267
|
+
account
|
|
3268
|
+
});
|
|
3269
|
+
}
|
|
3270
|
+
}),
|
|
3271
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the connect wallet process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
3272
|
+
});
|
|
3273
|
+
});
|
|
3274
|
+
}, [client, masterConfig, fetchWalletProviders, pushPage]);
|
|
3275
|
+
const handleRemoveUserEmail = react.useCallback(async params => {
|
|
3276
|
+
const {
|
|
3277
|
+
successPageDuration = 2000,
|
|
3278
|
+
stampWith,
|
|
3279
|
+
userId
|
|
3280
|
+
} = params || {};
|
|
3281
|
+
const s = await getSession();
|
|
3282
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
3283
|
+
if (!organizationId) {
|
|
3284
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3285
|
+
}
|
|
3286
|
+
try {
|
|
3287
|
+
return new Promise((resolve, reject) => {
|
|
3288
|
+
pushPage({
|
|
3289
|
+
key: "Remove Email",
|
|
3290
|
+
content: jsxRuntime.jsx(RemoveEmail.RemoveEmail, {
|
|
3291
|
+
successPageDuration: successPageDuration,
|
|
3292
|
+
...(userId && {
|
|
3293
|
+
userId
|
|
3294
|
+
}),
|
|
3295
|
+
...(stampWith && {
|
|
3296
|
+
stampWith
|
|
3297
|
+
}),
|
|
3298
|
+
onSuccess: userId => {
|
|
3299
|
+
resolve(userId);
|
|
3300
|
+
},
|
|
3301
|
+
onError: error => {
|
|
3302
|
+
reject(error);
|
|
3303
|
+
},
|
|
3304
|
+
...(organizationId !== undefined && {
|
|
3305
|
+
organizationId
|
|
3306
|
+
})
|
|
3307
|
+
}),
|
|
3308
|
+
showTitle: false,
|
|
3309
|
+
preventBack: true,
|
|
3310
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the remove email process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
3311
|
+
});
|
|
3312
|
+
});
|
|
3313
|
+
} catch (error) {
|
|
3314
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
3315
|
+
throw error;
|
|
3316
|
+
}
|
|
3317
|
+
throw new sdkTypes.ZeroXKeyError("Failed to remove user email.", sdkTypes.ZeroXKeyErrorCodes.UPDATE_USER_EMAIL_ERROR, error);
|
|
3318
|
+
}
|
|
3319
|
+
}, [getSession, pushPage]);
|
|
3320
|
+
const handleRemoveUserPhoneNumber = react.useCallback(async params => {
|
|
3321
|
+
const {
|
|
3322
|
+
successPageDuration = 2000,
|
|
3323
|
+
stampWith,
|
|
3324
|
+
userId
|
|
3325
|
+
} = params || {};
|
|
3326
|
+
const s = await getSession();
|
|
3327
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
3328
|
+
if (!organizationId) {
|
|
3329
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3330
|
+
}
|
|
3331
|
+
try {
|
|
3332
|
+
return new Promise((resolve, reject) => {
|
|
3333
|
+
pushPage({
|
|
3334
|
+
key: "Remove Phone Number",
|
|
3335
|
+
content: jsxRuntime.jsx(RemovePhoneNumber.RemovePhoneNumber, {
|
|
3336
|
+
successPageDuration: successPageDuration,
|
|
3337
|
+
...(userId && {
|
|
3338
|
+
userId
|
|
3339
|
+
}),
|
|
3340
|
+
...(stampWith && {
|
|
3341
|
+
stampWith
|
|
3342
|
+
}),
|
|
3343
|
+
onSuccess: userId => {
|
|
3344
|
+
resolve(userId);
|
|
3345
|
+
},
|
|
3346
|
+
onError: error => {
|
|
3347
|
+
reject(error);
|
|
3348
|
+
},
|
|
3349
|
+
...(organizationId !== undefined && {
|
|
3350
|
+
organizationId
|
|
3351
|
+
})
|
|
3352
|
+
}),
|
|
3353
|
+
showTitle: false,
|
|
3354
|
+
preventBack: true,
|
|
3355
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the remove phone number process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
3356
|
+
});
|
|
3357
|
+
});
|
|
3358
|
+
} catch (error) {
|
|
3359
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
3360
|
+
throw error;
|
|
3361
|
+
}
|
|
3362
|
+
throw new sdkTypes.ZeroXKeyError("Failed to remove user phone number.", sdkTypes.ZeroXKeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR, error);
|
|
3363
|
+
}
|
|
3364
|
+
}, [getSession, pushPage]);
|
|
3365
|
+
const handleSendTransaction = react.useCallback(async params => {
|
|
3366
|
+
const session = await getSession();
|
|
3367
|
+
const organizationId = params.organizationId || session?.organizationId;
|
|
3368
|
+
if (!organizationId) {
|
|
3369
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3370
|
+
}
|
|
3371
|
+
const {
|
|
3372
|
+
transaction,
|
|
3373
|
+
icon,
|
|
3374
|
+
stampWith,
|
|
3375
|
+
successPageDuration = 2000
|
|
3376
|
+
} = params;
|
|
3377
|
+
const {
|
|
3378
|
+
caip2
|
|
3379
|
+
} = transaction;
|
|
3380
|
+
const isSolanaTransaction = caip2.startsWith("solana:");
|
|
3381
|
+
return new Promise((resolve, reject) => {
|
|
3382
|
+
const action = async () => {
|
|
3383
|
+
const sendTransactionStatusId = isSolanaTransaction ? await solSendTransaction({
|
|
3384
|
+
organizationId,
|
|
3385
|
+
transaction: transaction,
|
|
3386
|
+
stampWith
|
|
3387
|
+
}) : await (async () => {
|
|
3388
|
+
const {
|
|
3389
|
+
from,
|
|
3390
|
+
to,
|
|
3391
|
+
value,
|
|
3392
|
+
data,
|
|
3393
|
+
nonce,
|
|
3394
|
+
gasLimit,
|
|
3395
|
+
maxFeePerGas,
|
|
3396
|
+
maxPriorityFeePerGas,
|
|
3397
|
+
sponsor
|
|
3398
|
+
} = transaction;
|
|
3399
|
+
const cleanedData = data && data !== "0x" && data !== "" ? data : undefined;
|
|
3400
|
+
const tx = {
|
|
3401
|
+
from,
|
|
3402
|
+
to,
|
|
3403
|
+
caip2,
|
|
3404
|
+
sponsor: sponsor ?? false,
|
|
3405
|
+
...(value ? {
|
|
3406
|
+
value
|
|
3407
|
+
} : {}),
|
|
3408
|
+
...(cleanedData ? {
|
|
3409
|
+
data: cleanedData
|
|
3410
|
+
} : {}),
|
|
3411
|
+
...(nonce ? {
|
|
3412
|
+
nonce
|
|
3413
|
+
} : {}),
|
|
3414
|
+
...(gasLimit ? {
|
|
3415
|
+
gasLimit
|
|
3416
|
+
} : {}),
|
|
3417
|
+
...(maxFeePerGas ? {
|
|
3418
|
+
maxFeePerGas
|
|
3419
|
+
} : {}),
|
|
3420
|
+
...(maxPriorityFeePerGas ? {
|
|
3421
|
+
maxPriorityFeePerGas
|
|
3422
|
+
} : {})
|
|
3423
|
+
};
|
|
3424
|
+
return ethSendTransaction({
|
|
3425
|
+
organizationId,
|
|
3426
|
+
transaction: tx,
|
|
3427
|
+
stampWith
|
|
3428
|
+
});
|
|
3429
|
+
})();
|
|
3430
|
+
if (!sendTransactionStatusId) {
|
|
3431
|
+
throw new sdkTypes.ZeroXKeyError("Missing sendTransactionStatusId", sdkTypes.ZeroXKeyErrorCodes.BAD_RESPONSE);
|
|
3432
|
+
}
|
|
3433
|
+
const pollResult = await pollTransactionStatus({
|
|
3434
|
+
organizationId,
|
|
3435
|
+
sendTransactionStatusId
|
|
3436
|
+
});
|
|
3437
|
+
const txDetails = pollResult;
|
|
3438
|
+
const txHash = txDetails.eth?.txHash ?? txDetails.solana?.signature ?? txDetails.txHash;
|
|
3439
|
+
return txHash ? {
|
|
3440
|
+
txHash
|
|
3441
|
+
} : {};
|
|
3442
|
+
};
|
|
3443
|
+
pushPage({
|
|
3444
|
+
key: "Send Transaction",
|
|
3445
|
+
showTitle: false,
|
|
3446
|
+
preventBack: true,
|
|
3447
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the transaction.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED)),
|
|
3448
|
+
content: jsxRuntime.jsx(SendTransaction.SendTransactionPage, {
|
|
3449
|
+
icon: icon ?? helpers$1.getChainLogo(caip2),
|
|
3450
|
+
action: action,
|
|
3451
|
+
caip2: caip2,
|
|
3452
|
+
successPageDuration: successPageDuration,
|
|
3453
|
+
onSuccess: () => resolve(),
|
|
3454
|
+
onError: err => reject(err)
|
|
3455
|
+
})
|
|
3456
|
+
});
|
|
3457
|
+
});
|
|
3458
|
+
}, [ethSendTransaction, getSession, pollTransactionStatus, pushPage, solSendTransaction]);
|
|
3459
|
+
const handleSendErc20Transfer = react.useCallback(async params => {
|
|
3460
|
+
const session = await getSession();
|
|
3461
|
+
const organizationId = params.organizationId || session?.organizationId;
|
|
3462
|
+
if (!organizationId) {
|
|
3463
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3464
|
+
}
|
|
3465
|
+
const {
|
|
3466
|
+
transfer,
|
|
3467
|
+
icon,
|
|
3468
|
+
stampWith,
|
|
3469
|
+
successPageDuration = 2000
|
|
3470
|
+
} = params;
|
|
3471
|
+
const {
|
|
3472
|
+
caip2
|
|
3473
|
+
} = transfer;
|
|
3474
|
+
return new Promise((resolve, reject) => {
|
|
3475
|
+
const action = async () => {
|
|
3476
|
+
const sendTransactionStatusId = await ethSendErc20Transfer({
|
|
3477
|
+
organizationId,
|
|
3478
|
+
transfer,
|
|
3479
|
+
stampWith
|
|
3480
|
+
});
|
|
3481
|
+
if (!sendTransactionStatusId) {
|
|
3482
|
+
throw new sdkTypes.ZeroXKeyError("Missing sendTransactionStatusId", sdkTypes.ZeroXKeyErrorCodes.BAD_RESPONSE);
|
|
3483
|
+
}
|
|
3484
|
+
const pollResult = await pollTransactionStatus({
|
|
3485
|
+
organizationId,
|
|
3486
|
+
sendTransactionStatusId
|
|
3487
|
+
});
|
|
3488
|
+
const txHash = pollResult?.eth?.txHash ?? pollResult?.txHash;
|
|
3489
|
+
return txHash ? {
|
|
3490
|
+
txHash
|
|
3491
|
+
} : {};
|
|
3492
|
+
};
|
|
3493
|
+
pushPage({
|
|
3494
|
+
key: "Send ERC20 Transfer",
|
|
3495
|
+
showTitle: false,
|
|
3496
|
+
preventBack: true,
|
|
3497
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the transaction.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED)),
|
|
3498
|
+
content: jsxRuntime.jsx(SendTransaction.SendTransactionPage, {
|
|
3499
|
+
icon: icon ?? helpers$1.getChainLogo(caip2),
|
|
3500
|
+
action: action,
|
|
3501
|
+
caip2: caip2,
|
|
3502
|
+
successPageDuration: successPageDuration,
|
|
3503
|
+
onSuccess: () => resolve(),
|
|
3504
|
+
onError: err => reject(err)
|
|
3505
|
+
})
|
|
3506
|
+
});
|
|
3507
|
+
});
|
|
3508
|
+
}, [ethSendErc20Transfer, getSession, pollTransactionStatus, pushPage]);
|
|
3509
|
+
const handleOnRamp = react.useCallback(async params => {
|
|
3510
|
+
const {
|
|
3511
|
+
walletAccount,
|
|
3512
|
+
fiatCurrencyAmount,
|
|
3513
|
+
fiatCurrencyCode,
|
|
3514
|
+
paymentMethod,
|
|
3515
|
+
countrySubdivisionCode,
|
|
3516
|
+
urlForSignature,
|
|
3517
|
+
countryCode,
|
|
3518
|
+
onrampProvider = "FIAT_ON_RAMP_PROVIDER_MOONPAY",
|
|
3519
|
+
sandboxMode = true,
|
|
3520
|
+
successPageDuration = 2000,
|
|
3521
|
+
openInNewTab = false
|
|
3522
|
+
} = params;
|
|
3523
|
+
const s = await getSession();
|
|
3524
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
3525
|
+
if (!organizationId) {
|
|
3526
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3527
|
+
}
|
|
3528
|
+
let cryptoCurrencyCode;
|
|
3529
|
+
let network;
|
|
3530
|
+
switch (true) {
|
|
3531
|
+
case walletAccount.addressFormat === "ADDRESS_FORMAT_ETHEREUM":
|
|
3532
|
+
cryptoCurrencyCode = sdkTypes.FiatOnRampCryptoCurrency.ETHEREUM;
|
|
3533
|
+
network = sdkTypes.FiatOnRampBlockchainNetwork.ETHEREUM;
|
|
3534
|
+
break;
|
|
3535
|
+
case walletAccount.addressFormat?.includes("ADDRESS_FORMAT_BITCOIN"):
|
|
3536
|
+
cryptoCurrencyCode = sdkTypes.FiatOnRampCryptoCurrency.BITCOIN;
|
|
3537
|
+
network = sdkTypes.FiatOnRampBlockchainNetwork.BITCOIN;
|
|
3538
|
+
break;
|
|
3539
|
+
case walletAccount.addressFormat === "ADDRESS_FORMAT_SOLANA":
|
|
3540
|
+
cryptoCurrencyCode = sdkTypes.FiatOnRampCryptoCurrency.SOLANA;
|
|
3541
|
+
network = sdkTypes.FiatOnRampBlockchainNetwork.SOLANA;
|
|
3542
|
+
break;
|
|
3543
|
+
default:
|
|
3544
|
+
cryptoCurrencyCode = sdkTypes.FiatOnRampCryptoCurrency.ETHEREUM;
|
|
3545
|
+
network = sdkTypes.FiatOnRampBlockchainNetwork.ETHEREUM;
|
|
3546
|
+
break;
|
|
3547
|
+
}
|
|
3548
|
+
const openNewTab = openInNewTab || isMobile;
|
|
3549
|
+
cryptoCurrencyCode = params.cryptoCurrencyCode || cryptoCurrencyCode;
|
|
3550
|
+
network = params.network || network;
|
|
3551
|
+
return new Promise((resolve, reject) => {
|
|
3552
|
+
const OnRampContainer = () => {
|
|
3553
|
+
const [completed, setCompleted] = react.useState(false);
|
|
3554
|
+
const pollingRef = react.useRef(null);
|
|
3555
|
+
const cleanup = () => {
|
|
3556
|
+
if (pollingRef.current) {
|
|
3557
|
+
clearInterval(pollingRef.current);
|
|
3558
|
+
pollingRef.current = null;
|
|
3559
|
+
}
|
|
3560
|
+
};
|
|
3561
|
+
react.useEffect(() => {
|
|
3562
|
+
return () => {
|
|
3563
|
+
cleanup();
|
|
3564
|
+
};
|
|
3565
|
+
}, []);
|
|
3566
|
+
const action = async () => {
|
|
3567
|
+
try {
|
|
3568
|
+
let onRampWindow = null;
|
|
3569
|
+
if (openNewTab) {
|
|
3570
|
+
onRampWindow = window.open("", "_blank");
|
|
3571
|
+
if (!onRampWindow) throw new Error("Failed to open On Ramp tab.");
|
|
3572
|
+
}
|
|
3573
|
+
const result = await client?.httpClient?.initFiatOnRamp({
|
|
3574
|
+
onrampProvider,
|
|
3575
|
+
walletAddress: walletAccount.address,
|
|
3576
|
+
network,
|
|
3577
|
+
cryptoCurrencyCode,
|
|
3578
|
+
sandboxMode,
|
|
3579
|
+
organizationId,
|
|
3580
|
+
...(fiatCurrencyCode ? {
|
|
3581
|
+
fiatCurrencyCode
|
|
3582
|
+
} : {}),
|
|
3583
|
+
...(fiatCurrencyAmount ? {
|
|
3584
|
+
fiatCurrencyAmount
|
|
3585
|
+
} : {}),
|
|
3586
|
+
...(paymentMethod ? {
|
|
3587
|
+
paymentMethod
|
|
3588
|
+
} : {}),
|
|
3589
|
+
...(countryCode ? {
|
|
3590
|
+
countryCode
|
|
3591
|
+
} : {}),
|
|
3592
|
+
...(countrySubdivisionCode ? {
|
|
3593
|
+
countrySubdivisionCode
|
|
3594
|
+
} : {}),
|
|
3595
|
+
...(sandboxMode !== undefined ? {
|
|
3596
|
+
sandboxMode
|
|
3597
|
+
} : {}),
|
|
3598
|
+
...(urlForSignature ? {
|
|
3599
|
+
urlForSignature
|
|
3600
|
+
} : {})
|
|
3601
|
+
});
|
|
3602
|
+
if (!result?.onRampUrl) throw new Error("Missing onRampUrl");
|
|
3603
|
+
if (openNewTab && onRampWindow) {
|
|
3604
|
+
onRampWindow.location.href = result.onRampUrl.toString();
|
|
3605
|
+
} else {
|
|
3606
|
+
const popupWidth = 500;
|
|
3607
|
+
const popupHeight = 600;
|
|
3608
|
+
const left = window.screenX + (window.innerWidth - popupWidth) / 2;
|
|
3609
|
+
const top = window.screenY + (window.innerHeight - popupHeight) / 2;
|
|
3610
|
+
onRampWindow = window.open(result.onRampUrl.toString(), "_blank", `width=${popupWidth},height=${popupHeight},top=${top},left=${left},scrollbars=yes,resizable=yes`);
|
|
3611
|
+
if (!onRampWindow) throw new Error("Failed to open On Ramp window.");
|
|
3612
|
+
}
|
|
3613
|
+
const onRampTransactionId = result.onRampTransactionId;
|
|
3614
|
+
if (!onRampTransactionId) throw new Error("No onRampTransactionId returned");
|
|
3615
|
+
return new Promise((resolveAction, rejectAction) => {
|
|
3616
|
+
pollingRef.current = setInterval(async () => {
|
|
3617
|
+
try {
|
|
3618
|
+
if (onrampProvider === "FIAT_ON_RAMP_PROVIDER_COINBASE" && onRampWindow?.closed) {
|
|
3619
|
+
cleanup();
|
|
3620
|
+
rejectAction(new Error("On-ramp popup closed by user"));
|
|
3621
|
+
return;
|
|
3622
|
+
}
|
|
3623
|
+
let currentUrl = "";
|
|
3624
|
+
try {
|
|
3625
|
+
currentUrl = onRampWindow?.location.href || "";
|
|
3626
|
+
} catch {}
|
|
3627
|
+
if (currentUrl && currentUrl.startsWith(window.location.origin)) {
|
|
3628
|
+
cleanup();
|
|
3629
|
+
onRampWindow?.close();
|
|
3630
|
+
setCompleted(true);
|
|
3631
|
+
resolveAction();
|
|
3632
|
+
return;
|
|
3633
|
+
}
|
|
3634
|
+
const resp = await client?.httpClient?.getOnRampTransactionStatus({
|
|
3635
|
+
transactionId: onRampTransactionId,
|
|
3636
|
+
refresh: true
|
|
3637
|
+
});
|
|
3638
|
+
const status = resp?.transactionStatus;
|
|
3639
|
+
if (["COMPLETED", "FAILED", "CANCELLED"].includes(status ?? "")) {
|
|
3640
|
+
cleanup();
|
|
3641
|
+
try {
|
|
3642
|
+
onRampWindow?.close();
|
|
3643
|
+
} catch {}
|
|
3644
|
+
setCompleted(true);
|
|
3645
|
+
resolveAction();
|
|
3646
|
+
}
|
|
3647
|
+
} catch (error) {
|
|
3648
|
+
console.warn("Polling error (ignored):", error);
|
|
3649
|
+
}
|
|
3650
|
+
}, 3000);
|
|
3651
|
+
});
|
|
3652
|
+
} catch (err) {
|
|
3653
|
+
cleanup();
|
|
3654
|
+
throw err;
|
|
3655
|
+
}
|
|
3656
|
+
};
|
|
3657
|
+
return jsxRuntime.jsx(OnRamp.OnRampPage, {
|
|
3658
|
+
icon: onrampProvider === "FIAT_ON_RAMP_PROVIDER_COINBASE" ? jsxRuntime.jsx(Svg.CoinbaseLogo, {
|
|
3659
|
+
className: "w-12 h-12"
|
|
3660
|
+
}) : jsxRuntime.jsx(Svg.MoonPayLogo, {
|
|
3661
|
+
className: "w-12 h-12"
|
|
3662
|
+
}),
|
|
3663
|
+
onrampProvider: onrampProvider,
|
|
3664
|
+
action: action,
|
|
3665
|
+
sandboxMode: sandboxMode,
|
|
3666
|
+
completed: completed,
|
|
3667
|
+
successPageDuration: successPageDuration,
|
|
3668
|
+
onSuccess: () => resolve(),
|
|
3669
|
+
onError: err => reject(err)
|
|
3670
|
+
});
|
|
3671
|
+
};
|
|
3672
|
+
pushPage({
|
|
3673
|
+
key: "Fiat OnRamp",
|
|
3674
|
+
content: jsxRuntime.jsx(OnRampContainer, {}),
|
|
3675
|
+
showTitle: false,
|
|
3676
|
+
preventBack: true,
|
|
3677
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the onramp process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
3678
|
+
});
|
|
3679
|
+
});
|
|
3680
|
+
}, [getSession, client, pushPage]);
|
|
3681
|
+
const handleVerifyAppProofs = react.useCallback(async params => {
|
|
3682
|
+
const {
|
|
3683
|
+
appProofs,
|
|
3684
|
+
successPageDuration = 3000,
|
|
3685
|
+
stampWith
|
|
3686
|
+
} = params || {};
|
|
3687
|
+
const s = await getSession();
|
|
3688
|
+
const organizationId = params?.organizationId || s?.organizationId;
|
|
3689
|
+
if (!organizationId) {
|
|
3690
|
+
throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
|
|
3691
|
+
}
|
|
3692
|
+
try {
|
|
3693
|
+
return new Promise((resolve, reject) => {
|
|
3694
|
+
pushPage({
|
|
3695
|
+
key: "Verify app proofs",
|
|
3696
|
+
content: jsxRuntime.jsx(Verify.VerifyPage, {
|
|
3697
|
+
appProofs: appProofs,
|
|
3698
|
+
onSuccess: () => {
|
|
3699
|
+
resolve();
|
|
3700
|
+
},
|
|
3701
|
+
onError: error => {
|
|
3702
|
+
reject(error);
|
|
3703
|
+
},
|
|
3704
|
+
successPageDuration: successPageDuration,
|
|
3705
|
+
...(stampWith && {
|
|
3706
|
+
stampWith
|
|
3707
|
+
}),
|
|
3708
|
+
...(organizationId !== undefined && {
|
|
3709
|
+
organizationId
|
|
3710
|
+
})
|
|
3711
|
+
}),
|
|
3712
|
+
showTitle: false,
|
|
3713
|
+
preventBack: true,
|
|
3714
|
+
onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the verify app proofs process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
|
|
3715
|
+
});
|
|
3716
|
+
});
|
|
3717
|
+
} catch (error) {
|
|
3718
|
+
if (error instanceof sdkTypes.ZeroXKeyError) {
|
|
3719
|
+
throw error;
|
|
3720
|
+
}
|
|
3721
|
+
throw new sdkTypes.ZeroXKeyError("Failed to verify app proofs.", sdkTypes.ZeroXKeyErrorCodes.VERIFY_APP_PROOFS_ERROR, error);
|
|
3722
|
+
}
|
|
3723
|
+
}, [getSession, pushPage]);
|
|
3724
|
+
react.useEffect(() => {
|
|
3725
|
+
if (proxyAuthConfigRef.current) return;
|
|
3726
|
+
// Only fetch the proxy auth config once. Use that to build the master config.
|
|
3727
|
+
const fetchProxyAuthConfig = async () => {
|
|
3728
|
+
try {
|
|
3729
|
+
let proxyAuthConfig;
|
|
3730
|
+
if (shouldFetchWalletKitConfig) {
|
|
3731
|
+
// Only fetch the proxy auth config if we have an authProxyId and the autoFetchWalletKitConfig param is enabled or not passed in.
|
|
3732
|
+
proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId,
|
|
3733
|
+
// Can assert safely. See shouldFetchWalletKitConfig definition.
|
|
3734
|
+
config.authProxyUrl);
|
|
3735
|
+
proxyAuthConfigRef.current = proxyAuthConfig;
|
|
3736
|
+
}
|
|
3737
|
+
setMasterConfig(buildConfig(proxyAuthConfig));
|
|
3738
|
+
} catch {
|
|
3739
|
+
setClientState(base.ClientState.Error);
|
|
3740
|
+
}
|
|
3741
|
+
};
|
|
3742
|
+
fetchProxyAuthConfig();
|
|
3743
|
+
}, []);
|
|
3744
|
+
react.useEffect(() => {
|
|
3745
|
+
// Start the client initialization process once we have the master config.
|
|
3746
|
+
if (!masterConfig) return;
|
|
3747
|
+
initializeClient();
|
|
3748
|
+
}, [masterConfig]);
|
|
3749
|
+
react.useEffect(() => {
|
|
3750
|
+
// Handle changes to the passed in config prop -- update the master config
|
|
3751
|
+
// Rebuild the master config with the updated config and stored proxyAuthConfig
|
|
3752
|
+
// If we don't have a stored proxyAuthConfig and we need to fetch it, we wait until that fetch is done in the other useEffect.
|
|
3753
|
+
// If shouldFetchWalletKitConfig is false, we'll never have a proxyAuthConfig to build the master config with, so this useEffect should always run.
|
|
3754
|
+
if (!proxyAuthConfigRef.current && shouldFetchWalletKitConfig) return;
|
|
3755
|
+
setMasterConfig(buildConfig(proxyAuthConfigRef.current ?? undefined));
|
|
3756
|
+
}, [config, proxyAuthConfigRef.current]);
|
|
3757
|
+
/**
|
|
3758
|
+
* @internal
|
|
3759
|
+
* We create `debouncedRefreshWallets()` so that multiple rapid wallet events
|
|
3760
|
+
* (for example, on Solana a single disconnect can emit several events we listen for)
|
|
3761
|
+
* only trigger `maybeRefreshWallets()` once.
|
|
3762
|
+
*
|
|
3763
|
+
* Defining the debounced function outside of the `useEffect` ensures all event
|
|
3764
|
+
* listeners in `initializeWalletProviderListeners` share the same instance, instead of creating
|
|
3765
|
+
* a new one on every render.
|
|
3766
|
+
*/
|
|
3767
|
+
const debouncedRefreshWallets = utils.useDebouncedCallback(maybeRefreshWallets, 100);
|
|
3768
|
+
const debouncedFetchWalletProviders = utils.useDebouncedCallback(fetchWalletProviders, 100);
|
|
3769
|
+
react.useEffect(() => {
|
|
3770
|
+
const handleUpdateState = async () => {
|
|
3771
|
+
// we only refresh the wallets if there is an active session
|
|
3772
|
+
// this is needed because a disconnect event can occur
|
|
3773
|
+
// while the user is unauthenticated
|
|
3774
|
+
//
|
|
3775
|
+
// WalletProviders state is updated regardless of session state
|
|
3776
|
+
const currentSession = await getSession();
|
|
3777
|
+
if (currentSession) {
|
|
3778
|
+
// this updates both the wallets and walletProviders state
|
|
3779
|
+
await debouncedRefreshWallets();
|
|
3780
|
+
} else {
|
|
3781
|
+
// this updates only the walletProviders state
|
|
3782
|
+
await debouncedFetchWalletProviders();
|
|
3783
|
+
}
|
|
3784
|
+
};
|
|
3785
|
+
let cleanup = () => {};
|
|
3786
|
+
initializeWalletProviderListeners(walletProviders, handleUpdateState).then(fn => {
|
|
3787
|
+
cleanup = fn;
|
|
3788
|
+
}).catch(err => {
|
|
3789
|
+
console.error("Failed to init providers:", err);
|
|
3790
|
+
});
|
|
3791
|
+
return () => {
|
|
3792
|
+
cleanup();
|
|
3793
|
+
};
|
|
3794
|
+
}, [walletProviders, getSession, debouncedRefreshWallets, debouncedFetchWalletProviders]);
|
|
3795
|
+
react.useEffect(() => {
|
|
3796
|
+
// 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.
|
|
3797
|
+
// This will ensure that they are always in sync and remove the need to setAuthState manually in other places.
|
|
3798
|
+
if (session && utils.isValidSession(session)) {
|
|
3799
|
+
setAuthState(base.AuthState.Authenticated);
|
|
3800
|
+
} else {
|
|
3801
|
+
setAuthState(base.AuthState.Unauthenticated);
|
|
3802
|
+
}
|
|
3803
|
+
}, [session]);
|
|
3804
|
+
react.useEffect(() => {
|
|
3805
|
+
// This will handle any redirect based oAuth. It then initializes the session. This is the last step before client is considered "ready"
|
|
3806
|
+
if (!client || !masterConfig) return;
|
|
3807
|
+
completeRedirectOauth().finally(() => {
|
|
3808
|
+
clearSessionTimeouts();
|
|
3809
|
+
// if auth or wallet connecting features are enabled, we want to fetch
|
|
3810
|
+
// the wallet providers to set the state
|
|
3811
|
+
if (masterConfig.walletConfig?.features?.auth || masterConfig.walletConfig?.features?.connecting) {
|
|
3812
|
+
fetchWalletProviders();
|
|
3813
|
+
}
|
|
3814
|
+
initializeSessions().finally(() => {
|
|
3815
|
+
// Set the client state to ready only after all initializations are done.
|
|
3816
|
+
setClientState(base.ClientState.Ready);
|
|
3817
|
+
});
|
|
3818
|
+
});
|
|
3819
|
+
return () => {
|
|
3820
|
+
clearSessionTimeouts();
|
|
3821
|
+
};
|
|
3822
|
+
}, [client]);
|
|
3823
|
+
return jsxRuntime.jsx(Types.ClientContext.Provider, {
|
|
3824
|
+
value: {
|
|
3825
|
+
session,
|
|
3826
|
+
allSessions,
|
|
3827
|
+
clientState,
|
|
3828
|
+
authState,
|
|
3829
|
+
user,
|
|
3830
|
+
wallets,
|
|
3831
|
+
walletProviders,
|
|
3832
|
+
config: masterConfig,
|
|
3833
|
+
httpClient: client?.httpClient,
|
|
3834
|
+
createHttpClient,
|
|
3835
|
+
createPasskey,
|
|
3836
|
+
logout,
|
|
3837
|
+
loginWithPasskey,
|
|
3838
|
+
signUpWithPasskey,
|
|
3839
|
+
fetchWalletProviders,
|
|
3840
|
+
connectWalletAccount,
|
|
3841
|
+
disconnectWalletAccount,
|
|
3842
|
+
switchWalletAccountChain,
|
|
3843
|
+
buildWalletLoginRequest,
|
|
3844
|
+
loginWithWallet,
|
|
3845
|
+
signUpWithWallet,
|
|
3846
|
+
loginOrSignupWithWallet,
|
|
3847
|
+
initOtp,
|
|
3848
|
+
verifyOtp,
|
|
3849
|
+
loginWithOtp,
|
|
3850
|
+
signUpWithOtp,
|
|
3851
|
+
completeOtp,
|
|
3852
|
+
loginWithOauth,
|
|
3853
|
+
signUpWithOauth,
|
|
3854
|
+
completeOauth,
|
|
3855
|
+
fetchWallets,
|
|
3856
|
+
fetchWalletAccounts,
|
|
3857
|
+
fetchPrivateKeys,
|
|
3858
|
+
refreshWallets,
|
|
3859
|
+
signMessage,
|
|
3860
|
+
signTransaction,
|
|
3861
|
+
ethSendTransaction,
|
|
3862
|
+
ethSendErc20Transfer,
|
|
3863
|
+
solSendTransaction,
|
|
3864
|
+
signAndSendTransaction,
|
|
3865
|
+
pollTransactionStatus,
|
|
3866
|
+
fetchUser,
|
|
3867
|
+
fetchOrCreateP256ApiKeyUser,
|
|
3868
|
+
fetchOrCreatePolicies,
|
|
3869
|
+
refreshUser,
|
|
3870
|
+
updateUserEmail,
|
|
3871
|
+
removeUserEmail,
|
|
3872
|
+
updateUserPhoneNumber,
|
|
3873
|
+
removeUserPhoneNumber,
|
|
3874
|
+
updateUserName,
|
|
3875
|
+
addOauthProvider,
|
|
3876
|
+
removeOauthProviders,
|
|
3877
|
+
addPasskey,
|
|
3878
|
+
removePasskeys,
|
|
3879
|
+
createWallet,
|
|
3880
|
+
createWalletAccounts,
|
|
3881
|
+
exportWallet,
|
|
3882
|
+
exportPrivateKey,
|
|
3883
|
+
exportWalletAccount,
|
|
3884
|
+
importWallet,
|
|
3885
|
+
importPrivateKey,
|
|
3886
|
+
deleteSubOrganization,
|
|
3887
|
+
storeSession,
|
|
3888
|
+
clearSession,
|
|
3889
|
+
clearAllSessions,
|
|
3890
|
+
refreshSession,
|
|
3891
|
+
getSession,
|
|
3892
|
+
getAllSessions,
|
|
3893
|
+
setActiveSession,
|
|
3894
|
+
clearUnusedKeyPairs,
|
|
3895
|
+
getActiveSessionKey,
|
|
3896
|
+
createApiKeyPair,
|
|
3897
|
+
getProxyAuthConfig,
|
|
3898
|
+
fetchBootProofForAppProof,
|
|
3899
|
+
verifyAppProofs,
|
|
3900
|
+
handleLogin,
|
|
3901
|
+
handleGoogleOauth,
|
|
3902
|
+
handleXOauth,
|
|
3903
|
+
handleDiscordOauth,
|
|
3904
|
+
handleAppleOauth,
|
|
3905
|
+
handleFacebookOauth,
|
|
3906
|
+
handleExportWallet,
|
|
3907
|
+
handleExportPrivateKey,
|
|
3908
|
+
handleExportWalletAccount,
|
|
3909
|
+
handleImportWallet,
|
|
3910
|
+
handleImportPrivateKey,
|
|
3911
|
+
handleUpdateUserEmail,
|
|
3912
|
+
handleUpdateUserPhoneNumber,
|
|
3913
|
+
handleUpdateUserName,
|
|
3914
|
+
handleAddOauthProvider,
|
|
3915
|
+
handleRemoveOauthProvider,
|
|
3916
|
+
handleAddPasskey,
|
|
3917
|
+
handleRemovePasskey,
|
|
3918
|
+
handleAddEmail,
|
|
3919
|
+
handleAddPhoneNumber,
|
|
3920
|
+
handleSignMessage,
|
|
3921
|
+
handleConnectExternalWallet,
|
|
3922
|
+
handleRemoveUserEmail,
|
|
3923
|
+
handleRemoveUserPhoneNumber,
|
|
3924
|
+
handleVerifyAppProofs,
|
|
3925
|
+
handleOnRamp,
|
|
3926
|
+
handleSendTransaction,
|
|
3927
|
+
handleSendErc20Transfer
|
|
3928
|
+
},
|
|
3929
|
+
children: children
|
|
3930
|
+
});
|
|
3931
|
+
};
|
|
3932
|
+
|
|
3933
|
+
exports.ClientProvider = ClientProvider;
|
|
3934
|
+
//# sourceMappingURL=Provider.js.map
|