UNPKG

@turnkey/core

Version:

A core JavaScript web and React Native package for interfacing with Turnkey's infrastructure.

114 lines (111 loc) 5.57 kB
import { CrossPlatformWalletStamper } from '../stamper.mjs'; import { CrossPlatformWalletConnector } from '../connector.mjs'; import { WalletInterfaceType, Chain } from '../../__types__/enums.mjs'; import { WalletConnectClient } from '../wallet-connect/client.mjs'; import { WalletConnectWallet } from '../wallet-connect/base.mjs'; class MobileWalletManager { /** * Constructs a MobileWalletManager that only uses WalletConnect. * * - Determines enabled chains based on provided namespaces for Ethereum and Solana. * - Initializes WalletConnect wallet interface and maps it to supported chains. * - Optionally enables stamping and connecting flows based on feature flags that live in the cfg. * - Sets up `CrossPlatformWalletStamper` and `CrossPlatformWalletConnector` if auth or connecting features are enabled. * * @param cfg - Wallet manager configuration (we only use WalletConnect fields). */ constructor(cfg) { // queue of async initialization functions this.initializers = []; // mapping of wallet interface types to their wallet instances this.wallets = {}; // maps a blockchain chain to its corresponding wallet interface types this.chainToInterfaces = {}; /** * Registers a wallet interface type as supporting a specific blockchain chain. * * @param chain - Chain (e.g., Ethereum, Solana). * @param interfaceType - Wallet interface type to associate with the chain. */ this.addChainInterface = (chain, interfaceType) => { if (!this.chainToInterfaces[chain]) this.chainToInterfaces[chain] = []; this.chainToInterfaces[chain].push(interfaceType); }; const ethereumNamespaces = cfg.chains.ethereum?.walletConnectNamespaces ?? []; const solanaNamespaces = cfg.chains.solana?.walletConnectNamespaces ?? []; const enableWalletConnectEvm = ethereumNamespaces.length > 0; const enableWalletConnectSol = solanaNamespaces.length > 0; const enableWalletConnect = enableWalletConnectEvm || enableWalletConnectSol; if (cfg.walletConnect && enableWalletConnect) { this.wcClient = new WalletConnectClient(); const wcUnified = new WalletConnectWallet(this.wcClient, undefined, { ethereumNamespaces, solanaNamespaces, }); this.wallets[WalletInterfaceType.WalletConnect] = wcUnified; // add async init step to the initializer queue this.initializers.push(() => wcUnified.init()); // register WalletConnect as a wallet interface for each enabled chain if (enableWalletConnectEvm) { this.addChainInterface(Chain.Ethereum, WalletInterfaceType.WalletConnect); } if (enableWalletConnectSol) { this.addChainInterface(Chain.Solana, WalletInterfaceType.WalletConnect); } } if (cfg.features?.auth) { this.stamper = new CrossPlatformWalletStamper(this.wallets); } if (cfg.features?.connecting) { this.connector = new CrossPlatformWalletConnector(this.wallets); } } /** * Initializes WalletConnect components and any registered wallet interfaces. * * - First initializes the low-level WalletConnect client with the provided config. * - Then initializes higher-level wallet interface `WalletConnectWallet` using registered async initializers. * * @param cfg - Wallet manager configuration used for initializing the WalletConnect client. */ async init(cfg) { if (this.wcClient) { await this.wcClient.init(cfg.walletConnect); } // we initialize the high-level WalletConnectWallet // we do this because we can't init this inside the constructor since it's async await Promise.all(this.initializers.map((fn) => fn())); } /** * Retrieves available wallet providers, optionally filtered by chain. * * - If a chain is specified, filters wallet interfaces that support that chain. * - Aggregates providers across all registered wallet interfaces. * - Filters WalletConnect results to match the specified chain. * * @param chain - Optional chain to filter providers by. * @returns A promise that resolves to an array of `WalletProvider` objects. * @throws {Error} If no wallet interface is registered for the given chain. */ async getProviders(chain) { if (chain) { const interfaceType = this.chainToInterfaces[chain]; if (!interfaceType || interfaceType.length === 0) { throw new Error(`No wallet supports chain: ${chain}`); } const walletsToQuery = interfaceType .map((iface) => this.wallets[iface]) .filter(Boolean); const providersArrays = await Promise.all(walletsToQuery.map((wallet) => wallet.getProviders())); // we still need to filter by chain because WalletConnect can return providers for multiple chains return providersArrays .flat() .filter((p) => p.chainInfo.namespace === chain); } const providersArrays = await Promise.all(Object.values(this.wallets).map((wallet) => wallet.getProviders())); return providersArrays.flat(); } } export { MobileWalletManager }; //# sourceMappingURL=manager.mjs.map