UNPKG

@dynamic-labs/sdk-react-core

Version:

A React SDK for implementing wallet web3 authentication and authorization to your website.

287 lines (284 loc) 15.7 kB
'use client' import { __awaiter } from '../../../../../../_virtual/_tslib.js'; import { StorageService, isMobile, UserRejectedRequestError } from '@dynamic-labs/utils'; import { isPhantomRedirectConnector } from '@dynamic-labs/wallet-connector-core'; import 'react'; import '../../../../context/DynamicContext/DynamicContext.js'; import '../../../../store/state/loadingAndLifecycle/loadingAndLifecycle.js'; import '@dynamic-labs/sdk-api-core'; import { logger } from '../../../../shared/logger.js'; import '@dynamic-labs/iconic'; import 'react/jsx-runtime'; import { useViewContext } from '../../../../context/ViewContext/ViewContext.js'; import '@dynamic-labs/wallet-book'; import { PHANTOM_SIGNATURE_STATE } from '../../../constants/localStorage.js'; import '../../../constants/colors.js'; import '../../../constants/values.js'; import '../../../../shared/consts/index.js'; import { dynamicEvents } from '../../../../events/dynamicEvents.js'; import '../../../../context/CaptchaContext/CaptchaContext.js'; import { useErrorContext } from '../../../../context/ErrorContext/ErrorContext.js'; import '@dynamic-labs/multi-wallet'; import 'react-international-phone'; import '../../../../store/state/nonce/nonce.js'; import { requiresTwoStepAuthentication } from '../../../functions/requiresTwoStepAuthentication/requiresTwoStepAuthentication.js'; import '../../../../store/state/projectSettings/projectSettings.js'; import '../../../../config/ApiEndpoint.js'; import '../../../../store/state/user/user.js'; import '../../../../locale/locale.js'; import '../../../../store/state/dynamicContextProps/dynamicContextProps.js'; import '../../../../store/state/primaryWalletId/primaryWalletId.js'; import '../../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js'; import '../../../../context/AccessDeniedContext/AccessDeniedContext.js'; import '../../../../context/AccountExistsContext/AccountExistsContext.js'; import '../../../../context/UserWalletsContext/UserWalletsContext.js'; import { getAuthMode } from '../../../../store/state/authMode/authMode.js'; import '../../../../context/VerificationContext/VerificationContext.js'; import 'react-dom'; import '../../../functions/compareChains/compareChains.js'; import '../../../../views/Passkey/utils/findPrimaryEmbeddedChain/findPrimaryEmbeddedChain.js'; import '../../../../context/ThemeContext/ThemeContext.js'; import '../../useUserUpdateRequest/useUpdateUser/userFieldsSchema.js'; import 'bs58'; import '@dynamic-labs/types'; import '../../../../context/SocialRedirectContext/SocialRedirectContext.js'; import '../../../../context/LoadingContext/LoadingContext.js'; import '../../../../context/WalletContext/WalletContext.js'; import '../../useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.js'; import 'yup'; import { useMockContext } from '../../../../context/MockContext/MockContext.js'; import '../../../../views/CollectUserDataView/useFields.js'; import '../../../../context/FieldsStateContext/FieldsStateContext.js'; import '../../../../context/UserFieldEditorContext/UserFieldEditorContext.js'; import '@dynamic-labs/rpc-providers'; import '../../../../store/state/walletOptions/walletOptions.js'; import { isSelectedWalletAlreadyConnected } from '../../../functions/isSelectedWalletAlreadyConnected/isSelectedWalletAlreadyConnected.js'; import 'react-i18next'; import '../../../../components/Accordion/components/AccordionItem/AccordionItem.js'; import '../../../../components/Alert/Alert.js'; import '../../../../components/ShadowDOM/ShadowDOM.js'; import '../../../../components/IconButton/IconButton.js'; import '../../../../components/InlineWidget/InlineWidget.js'; import '../../../../components/Input/Input.js'; import '../../../../components/IsBrowser/IsBrowser.js'; import '../../../../components/MenuList/Dropdown/Dropdown.js'; import '../../../../components/OverlayCard/OverlayCard.js'; import '../../../../components/Transition/ZoomTransition/ZoomTransition.js'; import '../../../../components/Transition/SlideInUpTransition/SlideInUpTransition.js'; import '../../../../components/Transition/OpacityTransition/OpacityTransition.js'; import '../../../../components/PasskeyCreatedSuccessBanner/PasskeyCreatedSuccessBanner.js'; import '../../../../components/Popper/Popper/Popper.js'; import '../../../../components/Popper/PopperContext/PopperContext.js'; import 'react-focus-lock'; import 'qrcode'; import 'formik'; import '../../useSubdomainCheck/useSubdomainCheck.js'; import '../../../../context/WalletGroupContext/WalletGroupContext.js'; import '../../../../context/IpConfigurationContext/IpConfigurationContext.js'; import '../../../../context/ConnectWithOtpContext/ConnectWithOtpContext.js'; import '../../../../widgets/DynamicBridgeWidget/views/WalletsView/components/SecondaryWallets/SecondaryWallets.js'; import '@hcaptcha/react-hcaptcha'; import '../../../../widgets/DynamicWidget/context/DynamicWidgetContext.js'; import '../../../../context/FooterAnimationContext/index.js'; import '../../../../context/ErrorContext/hooks/useErrorText/useErrorText.js'; import '../../../../context/PasskeyContext/PasskeyContext.js'; import '../../../../widgets/DynamicWidget/helpers/convertExchangeKeyAndProviderEnum.js'; import '../../../../store/state/sendBalances.js'; import '../../../../store/state/connectorsInitializing/connectorsInitializing.js'; import '../../../../components/OverlayCardBase/OverlayCardTarget/OverlayCardTarget.js'; import '../../../../widgets/DynamicWidget/components/DynamicWidgetHeader/DynamicWidgetHeader.js'; import '../../../../views/TransactionConfirmationView/TransactionConfirmationView.js'; import '../../../../widgets/DynamicWidget/views/ManagePasskeysWidgetView/PasskeyCard/PasskeyCard.js'; import '../../../../context/OnrampContext/OnrampContext.js'; import '../../../../widgets/DynamicWidget/views/ReceiveWalletFunds/ReceiveWalletFunds.js'; import '../../../../../index.js'; import '../../../../store/state/tokenBalances.js'; import '../../../../shared/utils/functions/getInitialUrl/getInitialUrl.js'; import { useInternalDynamicContext } from '../../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js'; const useHandleWalletItem = ({ allowAlreadyConnectedWallet, onQrCodeConnect, onConnectOnly, onCustodialWallet, onInstalledExtension, }) => { const { setMultiWalletWidgetState, setShowAuthFlow, setSelectedWalletConnectorKey, walletConnectorOptions, setQrcodeUri, setDesktopUri, user, linkedWallets, setLegacyIsVerifying, } = useInternalDynamicContext(); const { mockedSDK } = useMockContext(); const { setError, setErrorMessage } = useErrorContext(); const { pushView, clearStackAndPushInitialView, replaceView } = useViewContext(); const handleCustodialWalletClick = (walletConnector) => __awaiter(void 0, void 0, void 0, function* () { logger.debug('handleCustodialWalletClick', walletConnector); const twoStepAuthentication = requiresTwoStepAuthentication(walletConnector); logger.logVerboseTroubleshootingMessage('[handleCustodialWalletClick]', { twoStepAuthentication, }); setSelectedWalletConnectorKey(walletConnector.key); return onCustodialWallet({ requiresTwoStepAuthentication: twoStepAuthentication, walletConnector, }); }); const handleMobileWalletClick = (walletConnector) => __awaiter(void 0, void 0, void 0, function* () { var _a; logger.debug('handleMobileWalletClick', walletConnector); setSelectedWalletConnectorKey(walletConnector.key); // We need to set to LS when about to verify phantom wallet on mobile // because the deeplink interrupts this code execution and then redirects back on a new tab. // This resets all state (except for LS obviously). When we receive the phantom signature in this new tab, // we can't tell whether it's supposed to be used to sign a message, verify a wallet sign in/link, // or conclude a wallet transfer, which is why we need this LS variable: it will indicate whether it // is a signature, authentication or transfer. // Check method handleUserResponse in file useResponseHandlers, case 'signMessage'. if (walletConnector.key === 'phantom') { const currentState = StorageService.getItem(PHANTOM_SIGNATURE_STATE); StorageService.setItem(PHANTOM_SIGNATURE_STATE, { loseOriginalAccountOnTransfer: (_a = currentState === null || currentState === void 0 ? void 0 : currentState.loseOriginalAccountOnTransfer) !== null && _a !== void 0 ? _a : false, submittedAtTimestamp: new Date().toString(), verificationType: 'awaiting_verification', }); } const attemptConnection = () => { onConnectOnly({ shouldShowPendingConnectView: false, walletConnector }); }; pushView('mobile-wallet-redirect-view', { onRetry: attemptConnection }); attemptConnection(); }); const handleInstalledExtensionClick = (walletConnector) => __awaiter(void 0, void 0, void 0, function* () { logger.debug('handleInstalledExtensionClick', walletConnector); setSelectedWalletConnectorKey(walletConnector.key); return onInstalledExtension({ walletConnector }); }); const handleUninstalledClick = (walletConnector) => __awaiter(void 0, void 0, void 0, function* () { logger.debug('handleUninstalledClick', walletConnector); setSelectedWalletConnectorKey(walletConnector.key); if (!walletConnector.canConnectViaQrCode) { replaceView('no-qr-not-installed'); } else { onQrCodeConnect({ getAddressOpts: { onDesktopUri: (uri) => __awaiter(void 0, void 0, void 0, function* () { setDesktopUri(uri); }), onDisplayUri: (uri) => __awaiter(void 0, void 0, void 0, function* () { setQrcodeUri(uri); }), }, walletConnector, }); replaceView('qr-code'); } setError(undefined); }); const handleAlreadyConnectedWallet = (walletConnector) => __awaiter(void 0, void 0, void 0, function* () { logger.debug('handleAlreadyConnectedWallet', walletConnector); setShowAuthFlow(false); const connectedAccounts = yield walletConnector.getConnectedAccounts(); const activeAccountAlreadyLinked = linkedWallets.find((wallet) => { var _a; return wallet.address.toLowerCase() === ((_a = connectedAccounts[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()); }); logger.logVerboseTroubleshootingMessage('[handleAlreadyConnectedWallet]', { activeAccountAlreadyLinked, connectedAccounts, linkedWallets, walletConnectorKey: walletConnector.key, }); setSelectedWalletConnectorKey(walletConnector.key); if (!activeAccountAlreadyLinked) { setMultiWalletWidgetState('awaiting_signature', undefined, 'linking_new_wallet'); return; } const isTryingToUpdateUnknownWallet = activeAccountAlreadyLinked.connector.key === 'unknown'; if (isTryingToUpdateUnknownWallet) { //prompt the user to connect and sign with the wallet dynamicEvents.emit('triggerConnectAndSign', walletConnector); return; } setMultiWalletWidgetState('awaiting_account_switch', 'linking_new_wallet'); }); const openWallet = (walletKey, handlers) => { var _a; const { openMobileWallet = handleMobileWalletClick, openCustodialWallet = handleCustodialWalletClick, openExtensionWallet = handleInstalledExtensionClick, } = handlers || {}; const walletConnector = (_a = walletConnectorOptions.find((wallet) => wallet.key === walletKey)) === null || _a === void 0 ? void 0 : _a.walletConnector; if (!walletConnector) return; if (isMobile()) { openMobileWallet(walletConnector); } else if (walletConnector.canConnectViaCustodialService) { openCustodialWallet(walletConnector); } else if (walletConnector.isInstalledOnBrowser()) { openExtensionWallet(walletConnector); } }; const handleWalletItemClick = (wallet) => __awaiter(void 0, void 0, void 0, function* () { const { walletConnector, isInstalledOnBrowser } = wallet; const shouldEndWalletConnectorSession = walletConnector.connectedChain === 'FLOW' || isPhantomRedirectConnector(walletConnector) || // because some wallet connectors only supports one connection at a time, // we need to end the session (disconnect) when the user selects // a different wallet to connect with // a new connection is established a few steps further down !walletConnector.canHandleMultipleConnections; logger.logVerboseTroubleshootingMessage('[handleWalletItemClick]', { mockedSDK, shouldEndWalletConnectorSession, wallet, }); if (mockedSDK) return; if (shouldEndWalletConnectorSession) { yield walletConnector.endSession(); } setLegacyIsVerifying(false); const isMetamask = walletConnector.key === 'metamask'; const authMode = getAuthMode(); // in connect only we only allow one account to be connected in the same wallet // also this is only a feature in MM if (authMode !== 'connect-only' && isMetamask) { try { setSelectedWalletConnectorKey(walletConnector.key); pushView('pending-connect'); yield walletConnector.chooseAccountsToConnect(); } catch (error) { if (error instanceof UserRejectedRequestError) { setErrorMessage('connection_rejected'); clearStackAndPushInitialView(); return; } } } if (!allowAlreadyConnectedWallet && isSelectedWalletAlreadyConnected(linkedWallets, walletConnector, user) && walletConnector.connectedChain !== 'FLOW' && !walletConnector.isWalletConnect) { // wallet is already connected handleAlreadyConnectedWallet(walletConnector); } else if (walletConnector.canConnectViaCustodialService) { // providers like coinbase, blocto and dapper handleCustodialWalletClick(walletConnector); } else if (isMobile()) { // mobile wallets if (walletConnector.key === 'walletconnect') { pushView('wallet-connect-mobile-wallets-list'); } else { handleMobileWalletClick(walletConnector); } } else if (isInstalledOnBrowser) { // browser extensions or injected wallets handleInstalledExtensionClick(walletConnector); } else { // wallet requiring a qr code (wallet connect/coinbase wallet) handleUninstalledClick(walletConnector); } }); return { handleAlreadyConnectedWallet, handleCustodialWalletClick, handleInstalledExtensionClick, handleMobileWalletClick, handleUninstalledClick, handleWalletItemClick, openWallet, }; }; export { useHandleWalletItem };