UNPKG

@web3auth/no-modal

Version:
183 lines (177 loc) 6.79 kB
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import _objectSpread from '@babel/runtime/helpers/objectSpread2'; import { useMemo, createElement, useEffect, Fragment } from 'react'; import { defineChain } from 'viem'; import { webSocket, http, createConfig, WagmiProvider as WagmiProvider$1, useConfig, useReconnect, useAccountEffect } from 'wagmi'; import { injected } from 'wagmi/connectors'; import { defaultWagmiConfig } from './constants.js'; import { useWeb3Auth } from '../hooks/useWeb3Auth.js'; import { useWeb3AuthDisconnect } from '../hooks/useWeb3AuthDisconnect.js'; import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers'; import { WalletInitializationError } from '../../base/errors/index.js'; import { log } from '../../base/loglevel.js'; const _excluded = ["children"]; const WEB3AUTH_CONNECTOR_ID = "web3auth"; // Helper to initialize connectors for the given wallets // eslint-disable-next-line @typescript-eslint/no-explicit-any async function setupConnector(provider, config) { let connector = config.connectors.find(c => c.id === WEB3AUTH_CONNECTOR_ID); if (connector) return connector; // Create new connector if not already existing connector = injected({ target: { provider: provider, id: WEB3AUTH_CONNECTOR_ID, name: "Web3Auth" } }); const result = config._internal.connectors.setup(connector); config._internal.connectors.setState(current => [...current, result]); return result; } // Helper to connect a wallet and update wagmi state async function connectWeb3AuthWithWagmi(connector, config) { var _config$storage, _config$storage2; await Promise.all([(_config$storage = config.storage) === null || _config$storage === void 0 ? void 0 : _config$storage.removeItem(`${connector.id}.disconnected`), (_config$storage2 = config.storage) === null || _config$storage2 === void 0 ? void 0 : _config$storage2.setItem("recentConnectorId", connector.id)]); let chainId = await connector.getChainId(); if (!config.chains.find(c => c.id === chainId)) { chainId = config.chains[0].id; } const accounts = await connector.getAccounts(); const connections = new Map([[connector.uid, { accounts: [accounts[0]], chainId, connector }]]); config.setState(state => _objectSpread(_objectSpread({}, state), {}, { chainId, connections, current: connector.uid, status: "connected" })); } async function disconnectWeb3AuthFromWagmi(config) { config._internal.connectors.setState(prev => prev.filter(c => c.id !== WEB3AUTH_CONNECTOR_ID)); config.setState(state => _objectSpread(_objectSpread({}, state), {}, { chainId: state.chainId, connections: new Map(), current: undefined, status: "disconnected" })); } function Web3AuthWagmiProvider({ children }) { const { isConnected, provider } = useWeb3Auth(); const { disconnect } = useWeb3AuthDisconnect(); const wagmiConfig = useConfig(); const { reconnect } = useReconnect(); useAccountEffect({ onDisconnect: async () => { log.info("Disconnected from wagmi"); if (isConnected) await disconnect(); } }); useEffect(() => { (async () => { if (isConnected && provider) { const connector = await setupConnector(provider, wagmiConfig); if (!connector) { throw new Error("Failed to setup connector"); } await connectWeb3AuthWithWagmi(connector, wagmiConfig); reconnect(); } else if (!isConnected) { if (wagmiConfig.state.status === "connected") { await disconnectWeb3AuthFromWagmi(wagmiConfig); } } })(); }, [isConnected, wagmiConfig, provider, reconnect]); return createElement(Fragment, null, children); } function WagmiProvider(_ref) { let { children } = _ref, props = _objectWithoutProperties(_ref, _excluded); const { config } = props; const { web3Auth, isInitialized } = useWeb3Auth(); const finalConfig = useMemo(() => { var _web3Auth$coreOptions; web3Auth === null || web3Auth === void 0 || web3Auth.setAnalyticsProperties({ wagmi_enabled: true }); if (!isInitialized) return defaultWagmiConfig; const finalConfig = _objectSpread(_objectSpread({ ssr: true }, config), {}, { chains: undefined, connectors: [], transports: {}, multiInjectedProviderDiscovery: false, client: undefined }); const wagmiChains = []; if (isInitialized && web3Auth !== null && web3Auth !== void 0 && (_web3Auth$coreOptions = web3Auth.coreOptions) !== null && _web3Auth$coreOptions !== void 0 && _web3Auth$coreOptions.chains) { var _web3Auth$currentChai; const defaultChainId = (_web3Auth$currentChai = web3Auth.currentChain) === null || _web3Auth$currentChai === void 0 ? void 0 : _web3Auth$currentChai.chainId; const chains = web3Auth.coreOptions.chains.filter(chain => chain.chainNamespace === CHAIN_NAMESPACES.EIP155); if (chains.length === 0) throw WalletInitializationError.invalidParams("No valid chains found in web3auth config for wagmi."); chains.forEach(chain => { const wagmiChain = defineChain({ id: Number.parseInt(chain.chainId, 16), // id in number form name: chain.displayName, rpcUrls: { default: { http: [chain.rpcTarget], webSocket: [chain.wsTarget] } }, blockExplorers: chain.blockExplorerUrl ? { default: { name: "explorer", // TODO: correct name if chain config has it url: chain.blockExplorerUrl } } : undefined, nativeCurrency: { name: chain.tickerName, symbol: chain.ticker, decimals: chain.decimals || 18 } }); if (defaultChainId === chain.chainId) { wagmiChains.unshift(wagmiChain); } else { wagmiChains.push(wagmiChain); } finalConfig.transports[wagmiChain.id] = chain.wsTarget ? webSocket(chain.wsTarget) : http(chain.rpcTarget); }); finalConfig.chains = [wagmiChains[0], ...wagmiChains.slice(1)]; } if (!finalConfig.chains) return; return createConfig(finalConfig); }, [config, web3Auth, isInitialized]); return createElement(WagmiProvider$1, // typecast to WagmiProviderPropsBase to avoid type error // as we are omitting the config prop from WagmiProviderProps // and creating a new config object with the finalConfig _objectSpread(_objectSpread({}, props), {}, { config: finalConfig, reconnectOnMount: false }), createElement(Web3AuthWagmiProvider, null, children)); } export { WagmiProvider };