UNPKG

@funkit/wagmi-tools

Version:
224 lines (223 loc) 7.41 kB
// src/connector/funkitWagmiConnectorWallet.ts import { FUNKIT_CONNECT_SUPPORTED_CHAINS_INFO_LIST } from "@funkit/chains"; import { AddressZero, Auth, FunWallet, configureEnvironment, getEnvOptions } from "@funkit/core"; import { ChainNotConfiguredError, createConnector, normalizeChainId } from "@wagmi/core"; import { SwitchChainError, UserRejectedRequestError, numberToHex } from "viem"; var ERROR_PREFIX = "FunkitWagmiConnectorError"; var ConnectorEvent = { change: "change", disconnect: "disconnect", error: "error", message: "message", accountsChanged: "accountsChanged", chainChanged: "chainChanged" }; funkitWagmiConnectorWallet.type = "funkitWagmiConnectorWallet"; function funkitWagmiConnectorWallet() { let _privyProvider; let _fwIndex; let _fwAuth = null; let _funWallet = null; return createConnector( ({ chains = FUNKIT_CONNECT_SUPPORTED_CHAINS_INFO_LIST, emitter }) => ({ id: "funkitConnector", name: "Funkit Connector", type: funkitWagmiConnectorWallet.type, /**=============================== * Custom Funkit Connector Methods *================================*/ getFunWallet() { return _funWallet; }, getAuth() { return _fwAuth; }, getInternalConfigs() { return { _privyProvider, _fwIndex }; }, async beforeConnect({ provider, index }) { if (!provider) { throw new Error( `${ERROR_PREFIX}:beforeConnect - Missing provider param` ); } if (index == null || typeof index !== "number") { throw new Error( `${ERROR_PREFIX}:beforeConnect - Invalid index param` ); } _privyProvider = provider; _fwIndex = index; }, /**========================= * Wagmi Connector Methods *=========================*/ // Optional function for running when the connector is first created async setup() { return; }, // Function for connecting the connector. async connect({ chainId }) { const provider = await this.getProvider(); if (!provider) { throw new Error( `${ERROR_PREFIX}: Ensure beforeConnect() is called before connect()` ); } provider.on(ConnectorEvent.accountsChanged, this.onAccountsChanged); provider.on(ConnectorEvent.disconnect, this.onDisconnect); provider.on(ConnectorEvent.chainChanged, this.onChainChanged); emitter.emit(ConnectorEvent.message, { type: "connecting" }); _fwAuth = new Auth({ provider }); const walletUniqueId = await _fwAuth.getWalletUniqueId(_fwIndex); const userId = await _fwAuth.getUserId(); _funWallet = new FunWallet({ users: [{ userId }], uniqueId: walletUniqueId }); const [newAccountAddress, curChainId] = await Promise.all([ _funWallet.getAddress(), this.getChainId() ]); let currentChainId = curChainId; if (chainId && currentChainId !== chainId) { const chain = await this.switchChain?.({ chainId }).catch( (error) => { if (error.code === UserRejectedRequestError.code) { throw error; } return { id: currentChainId }; } ); currentChainId = chain?.id ?? currentChainId; } return { accounts: [newAccountAddress], chainId: currentChainId }; }, // Function for disconnecting the connector. async disconnect() { const provider = await this.getProvider(); provider.removeListener( ConnectorEvent.accountsChanged, this.onAccountsChanged ); provider.removeListener( ConnectorEvent.disconnect, this.onDisconnect.bind(this) ); provider.removeListener( ConnectorEvent.chainChanged, this.onDisconnect ); _funWallet = null; _fwAuth = null; }, // Function that returns the connected accounts for the connector. async getAccounts() { if (_funWallet == null) { return [AddressZero]; } return [await _funWallet.getAddress()]; }, // Function that returns the connected chain ID for the connector. async getChainId() { const provider = await this.getProvider(); const chainId = provider.chainId ?? await provider?.request({ method: "eth_chainId" }); return normalizeChainId(chainId); }, // Function that returns the underlying provider interface for internal use throughout the connector. async getProvider() { return _privyProvider; }, // Function that returns whether the connector has connected previously and is still authorized. async isAuthorized() { try { const accounts = await this.getAccounts(); return _funWallet != null && _fwAuth != null && !!accounts.length; } catch { return false; } }, // Optional function for switching the connector's active chain async switchChain({ chainId }) { try { const newChain = chains.find((chain) => chain?.id === chainId); if (!newChain) { throw new SwitchChainError(new ChainNotConfiguredError()); } const curEnv = getEnvOptions(); await configureEnvironment({ ...curEnv, chain: chainId }); const provider = await this.getProvider(); const chainIdHex = numberToHex(newChain.id); await provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: chainIdHex }] }); _fwAuth = new Auth({ provider }); const walletUniqueId = await _fwAuth.getWalletUniqueId(_fwIndex); const userId = await _fwAuth.getUserId(); _funWallet = new FunWallet({ users: [{ userId }], uniqueId: walletUniqueId }); emitter.emit(ConnectorEvent.change, { chainId: newChain.id, accounts: await this.getAccounts() }); return newChain; } catch (err) { console.error(`${ERROR_PREFIX}: Failed to switch chain`, err); throw err; } }, /**========================= * Wagmi Connector Events *=========================*/ // Function for subscribing to account changes internally in the connector. onAccountsChanged() { emitter.emit(ConnectorEvent.disconnect); }, // Function for subscribing to chain changes internally in the connector. onChainChanged(chainId) { const normalizedChainId = normalizeChainId(chainId); emitter.emit(ConnectorEvent.change, { chainId: normalizedChainId }); }, // Function for subscribing to disconnection events internally in the connector. onDisconnect(error) { if (error) { console.error(`${ERROR_PREFIX}: Error during disconnection`, error); } emitter.emit(ConnectorEvent.disconnect); } }) ); } export { funkitWagmiConnectorWallet }; //# sourceMappingURL=index.js.map