UNPKG

@sky-mavis/tanto-widget

Version:
126 lines (122 loc) 3.97 kB
'use strict'; var jsxRuntime = require('@emotion/react/jsx-runtime'); var reactQuery = require('@tanstack/react-query'); var react = require('react'); var uuid = require('uuid'); var wagmi = require('wagmi'); var useAccountSwitch = require('../../hooks/useAccountSwitch.cjs'); var useAuthEffect = require('../../hooks/useAuthEffect.cjs'); var queries = require('../../services/queries.cjs'); var common = require('../../utils/common.cjs'); var errors = require('../../utils/errors.cjs'); var siwe = require('../../utils/siwe.cjs'); var walletDetection = require('../../utils/walletDetection.cjs'); var useTantoConfig = require('../tanto/useTantoConfig.cjs'); var AuthContext = require('./AuthContext.cjs'); var useWaypointMessageHandler = require('./useWaypointMessageHandler.cjs'); function AuthProvider({ children }) { const { createAccountOnConnect: enableAuth = false, clientId, __internal_baseUrl } = useTantoConfig.useTantoConfig(); const { address, chainId, connector } = wagmi.useAccount(); const { signMessageAsync } = wagmi.useSignMessage(); const { disconnect } = wagmi.useDisconnect(); const [isSigningIn, setIsSigningIn] = react.useState(false); const [error, setError] = react.useState(null); const currentSignInRef = react.useRef(null); const { mutateAsync: generateNonce } = reactQuery.useMutation(queries.mutation.generateNonce()); const { mutateAsync: createAccount } = reactQuery.useMutation(queries.mutation.createAccount()); const reset = react.useCallback(() => { setIsSigningIn(false); setError(null); currentSignInRef.current = null; }, []); const signIn = react.useCallback(async () => { if (!enableAuth || !address || !chainId || isSigningIn) return; const sessionId = uuid.v4(); currentSignInRef.current = sessionId; setIsSigningIn(true); setError(null); try { // Wait for WC (in case of connect to metamask) switch chain if (walletDetection.isWCConnector(connector?.id)) await common.delay(1_000); if (walletDetection.isWaypointConnector(connector?.id)) return; const { nonce, expirationTime, issuedAt, notBefore } = await generateNonce({ baseUrl: __internal_baseUrl, address, clientId }); const message = siwe.generateSiweMessage({ address, chainId, nonce, expirationTime, issuedAt, notBefore }); const signature = await signMessageAsync({ message }); if (currentSignInRef.current !== sessionId) return; const { idToken } = await createAccount({ baseUrl: __internal_baseUrl, message, signature, clientId }); useAuthEffect.authEventEmitter.emit('success', { address, chainId, token: idToken }); } catch (error) { if (currentSignInRef.current !== sessionId) return; const authError = error instanceof Error ? error : new errors.TantoWidgetError(errors.TantoWidgetErrorCodes.CREATE_ACCOUNT_FAILED, 'Failed to create account'); console.debug('Auth error:', authError); setError(authError); useAuthEffect.authEventEmitter.emit('failed', { error: authError }); disconnect(); } finally { setIsSigningIn(false); } }, [enableAuth, address, chainId, isSigningIn, connector?.id, generateNonce, signMessageAsync, createAccount, clientId, disconnect]); useAccountSwitch.useAccountSwitch(signIn); useWaypointMessageHandler.useWaypointMessageHandler(enableAuth); const contextValue = react.useMemo(() => ({ enable: enableAuth, error, isSigningIn, signIn, reset }), [enableAuth, error, isSigningIn, signIn, reset]); return jsxRuntime.jsx(AuthContext.AuthContext.Provider, { value: contextValue, children: children }); } exports.AuthProvider = AuthProvider;