UNPKG

@web3auth/no-modal

Version:
207 lines (203 loc) 8.39 kB
'use strict'; var _objectSpread = require('@babel/runtime/helpers/objectSpread2'); var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties'); var client = require('@solana/client'); var reactHooks = require('@solana/react-hooks'); var react = require('react'); require('@babel/runtime/helpers/defineProperty'); require('@segment/analytics-next'); var loglevel = require('../../base/loglevel.js'); var baseControllers = require('@toruslabs/base-controllers'); require('@toruslabs/session-manager'); require('@web3auth/auth'); require('../../base/errors/index.js'); var utils = require('../../base/utils.js'); require('../../base/wallet/index.js'); require('../../base/connector/connectorStatus.js'); require('../../base/connector/constants.js'); require('jwt-decode'); require('../../base/constants.js'); require('../../base/plugin/errors.js'); require('../../base/plugin/IPlugin.js'); require('../context/Web3AuthInnerContext.js'); var useChain = require('../hooks/useChain.js'); require('../context/WalletServicesInnerContext.js'); var useWeb3Auth = require('../hooks/useWeb3Auth.js'); const _excluded = ["children"]; const DEVNET_ENDPOINT = "https://api.devnet.solana.com"; function placeholderRpc(isInitialized, web3Auth) { var _web3Auth$coreOptions; if (!isInitialized || !(web3Auth !== null && web3Auth !== void 0 && (_web3Auth$coreOptions = web3Auth.coreOptions) !== null && _web3Auth$coreOptions !== void 0 && _web3Auth$coreOptions.chains)) { return { rpcTarget: DEVNET_ENDPOINT }; } const solanaChains = web3Auth.coreOptions.chains.filter(c => c.chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA); const current = web3Auth.currentChain; const chain = (current === null || current === void 0 ? void 0 : current.chainNamespace) === baseControllers.CHAIN_NAMESPACES.SOLANA ? current : solanaChains[0]; if (!chain) return { rpcTarget: DEVNET_ENDPOINT }; return { rpcTarget: chain.rpcTarget, wsTarget: chain.wsTarget }; } function makePlaceholder(rpc) { return client.createClient({ endpoint: rpc.rpcTarget, websocketEndpoint: rpc.wsTarget, walletConnectors: [] }); } function dispose(client) { client.destroy(); } function resolveSolanaChain(web3Auth, connection) { var _web3Auth$coreOptions3; const currentChain = web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.currentChain; if ((currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) === baseControllers.CHAIN_NAMESPACES.SOLANA) { return currentChain; } const connectedScope = connection !== null && connection !== void 0 && connection.solanaWallet && "scope" in connection.solanaWallet && typeof connection.solanaWallet.scope === "string" ? connection.solanaWallet.scope : null; if (connectedScope) { var _web3Auth$coreOptions2; const connectedChain = web3Auth === null || web3Auth === void 0 || (_web3Auth$coreOptions2 = web3Auth.coreOptions.chains) === null || _web3Auth$coreOptions2 === void 0 ? void 0 : _web3Auth$coreOptions2.find(chain => { return chain.chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA && utils.getCaipChainId(chain) === connectedScope; }); if (connectedChain) return connectedChain; } return (web3Auth === null || web3Auth === void 0 || (_web3Auth$coreOptions3 = web3Auth.coreOptions.chains) === null || _web3Auth$coreOptions3 === void 0 ? void 0 : _web3Auth$coreOptions3.find(chain => chain.chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA)) || null; } /** * Builds the SolanaClient for Framework Kit React hooks. * For multichain wallets, keep the Solana client warm across namespace switches so * switching back to Solana can reuse the existing wallet session. */ function useFrameworkKitSolanaClient() { const { isConnected, connection, web3Auth, isInitialized } = useWeb3Auth.useWeb3Auth(); const { chainId, chainNamespace } = useChain.useChain(); const solClientRef = react.useRef(null); const connectedClientRef = react.useRef(null); const [client$1, setClient] = react.useState(() => { const c = makePlaceholder({ rpcTarget: DEVNET_ENDPOINT }); solClientRef.current = c; return c; }); react.useEffect(() => { if (isInitialized) web3Auth === null || web3Auth === void 0 || web3Auth.setAnalyticsProperties({ solana_framework_kit_enabled: true }); }, [isInitialized, web3Auth]); react.useEffect(() => () => { const connectedClient = connectedClientRef.current; const currentClient = solClientRef.current; if (currentClient) { dispose(currentClient); solClientRef.current = null; } if (connectedClient && connectedClient !== currentClient) { dispose(connectedClient); } connectedClientRef.current = null; }, []); react.useEffect(() => { let stale = false; const adopt = nextClient => { if (stale) { dispose(nextClient); return; } const prevClient = solClientRef.current; if (prevClient === nextClient) return; if (prevClient) dispose(prevClient); solClientRef.current = nextClient; setClient(nextClient); }; (async () => { const rpc = placeholderRpc(isInitialized, web3Auth); const conn = connection; const currentChain = web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.currentChain; if ((currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) !== baseControllers.CHAIN_NAMESPACES.SOLANA) { adopt(makePlaceholder(rpc)); return; } const preferredSolanaChain = resolveSolanaChain(web3Auth, conn); const shouldKeepSolanaClient = isConnected && Boolean(conn === null || conn === void 0 ? void 0 : conn.solanaWallet) && Boolean(preferredSolanaChain) && // only manage the client for the primary connector (conn === null || conn === void 0 ? void 0 : conn.connectorName) === (web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.primaryConnectorName); if (!shouldKeepSolanaClient) { const connectedClient = connectedClientRef.current; connectedClientRef.current = null; if (connectedClient) { dispose(connectedClient); } adopt(makePlaceholder(rpc)); return; } try { const solanaWalletId = "wallet-standard:" + conn.connectorName; const connector = client.createWalletStandardConnector(conn.solanaWallet, { id: solanaWalletId, name: conn.connectorName }); const { rpcTarget, wsTarget } = preferredSolanaChain; const wired = client.createClient({ endpoint: rpcTarget, websocketEndpoint: wsTarget, walletConnectors: [connector] }); await wired.actions.connectWallet(solanaWalletId, { autoConnect: true }); if (stale) { dispose(wired); return; } const prevConnectedClient = connectedClientRef.current; connectedClientRef.current = wired; if (chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA && (currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) === baseControllers.CHAIN_NAMESPACES.SOLANA) { adopt(wired); } else { adopt(makePlaceholder(rpc)); } if (prevConnectedClient && prevConnectedClient !== wired) { dispose(prevConnectedClient); } } catch (e) { loglevel.log.error("Failed to create or connect Solana client", e); adopt(makePlaceholder(rpc)); } })(); return () => { stale = true; }; }, [isConnected, connection === null || connection === void 0 ? void 0 : connection.solanaWallet, chainId, chainNamespace, web3Auth, isInitialized, connection === null || connection === void 0 ? void 0 : connection.connectorName]); return client$1; } function SolanaProvider(_ref) { let { children } = _ref, props = _objectWithoutProperties(_ref, _excluded); const client = useFrameworkKitSolanaClient(); return react.createElement(reactHooks.SolanaProvider, _objectSpread(_objectSpread({}, props), {}, { client, walletPersistence: false, children })); } exports.SolanaProvider = SolanaProvider;