UNPKG

@web3-wallet/core

Version:
109 lines (108 loc) 4.2 kB
import { create } from 'zustand'; import { persist } from 'zustand/middleware'; import { WalletConnectionStatus } from './types'; export const isWallet = (connectorOrWallet) => typeof connectorOrWallet.getConnector === 'function'; export const createCurrentWallet = (connectorsOrWallets, options) => { const { defaultCurrentWallet, persistKey = '@web3-wallet/current-wallet' } = options ?? {}; const connectors = connectorsOrWallets.map((v) => isWallet(v) ? v.getConnector() : v); const getConnector = (walletName) => { return connectors.find((v) => v.walletName === walletName); }; const currentWalletName = defaultCurrentWallet || connectors[0].walletName; const DEFAULT_STATE = { connectionStatus: WalletConnectionStatus.Untouched, walletName: currentWalletName, ...getConnector(currentWalletName).store.getState(), }; const store = create()(persist(() => DEFAULT_STATE, { name: persistKey, version: 0, partialize: ({ walletName, connectionStatus }) => ({ isConnecting: false, chainId: undefined, accounts: [], walletName, connectionStatus, }), })); const getCurrentConnector = () => { const walletName = store.getState().walletName; const connector = getConnector(walletName); if (connector) return connector; console.debug(`Wallet ${walletName}, don't exist, reset current wallet to ${connectors[0].walletName}`); store.setState({ walletName: connectors[0].walletName, connectionStatus: WalletConnectionStatus.Untouched, }); return connectors[0]; }; let unsubscribe; const switchCurrentWallet = (walletName) => { if (getConnector(walletName)) { store.setState({ walletName, ...getConnector(walletName).store.getState(), }); unsubscribe?.(); unsubscribe = getConnector(walletName).store.subscribe((state) => { // copy the wallet store state to current wallet store store.setState({ ...state, }); }); } else { console.debug(`Wallet '${walletName}' don't exists`); } }; // update current wallet store switchCurrentWallet(store.getState().walletName); const getConnect = (walletName) => async (...args) => { const connector = walletName ? getConnector(walletName) : getCurrentConnector(); const result = await connector.connect(...args); store.setState({ walletName: connector.walletName, connectionStatus: WalletConnectionStatus.Connected, }); return result; }; const autoConnect = async (...args) => { const connector = getCurrentConnector(); if (store.getState().connectionStatus === WalletConnectionStatus.Disconnected) { return false; } const result = await connector.autoConnect(...args); store.setState({ walletName: connector.walletName, connectionStatus: WalletConnectionStatus.Connected, }); return result; }; const disconnect = async (...args) => { const connector = getCurrentConnector(); const result = await connector.disconnect(...args); store.setState({ connectionStatus: WalletConnectionStatus.Disconnected, }); return result; }; return { getWalletName: () => getCurrentConnector().walletName, getStore: () => store, getConnector: getCurrentConnector, connect: getConnect(), autoConnect, disconnect, watchAsset: (...args) => getCurrentConnector().watchAsset(...args), detectProvider: () => getCurrentConnector().detectProvider(), // current wallet only apis switchCurrentWallet, connectAsCurrentWallet: (walletName, ...args) => { switchCurrentWallet(walletName); return getConnect(walletName)(...args); }, }; };