UNPKG

@reown/appkit-controllers

Version:

The full stack toolkit to build onchain app UX.

177 lines 8.08 kB
import { useCallback } from 'react'; import { useSnapshot } from 'valtio'; import { ConstantsUtil } from '@reown/appkit-common'; import { AlertController } from '../src/controllers/AlertController.js'; import { AssetController } from '../src/controllers/AssetController.js'; import { ChainController } from '../src/controllers/ChainController.js'; import { ConnectionController } from '../src/controllers/ConnectionController.js'; import { ConnectorController } from '../src/controllers/ConnectorController.js'; import { OptionsController } from '../src/controllers/OptionsController.js'; import { ConnectionControllerUtil } from '../src/utils/ConnectionControllerUtil.js'; import { CoreHelperUtil } from '../src/utils/CoreHelperUtil.js'; import { AssetUtil, StorageUtil } from './utils.js'; // -- Hooks ------------------------------------------------------------ export function useAppKitNetworkCore() { const { activeCaipNetwork } = useSnapshot(ChainController.state); return { caipNetwork: activeCaipNetwork, chainId: activeCaipNetwork?.id, caipNetworkId: activeCaipNetwork?.caipNetworkId }; } export function useAppKitAccount(options) { const state = useSnapshot(ChainController.state); const { activeConnectorIds } = useSnapshot(ConnectorController.state); const chainNamespace = options?.namespace || state.activeChain; if (!chainNamespace) { return { allAccounts: [], address: undefined, caipAddress: undefined, status: undefined, isConnected: false, embeddedWalletInfo: undefined }; } const chainAccountState = state.chains.get(chainNamespace)?.accountState; const authConnector = ConnectorController.getAuthConnector(chainNamespace); const activeConnectorId = activeConnectorIds[chainNamespace]; const connections = ConnectionController.getConnections(chainNamespace); const allAccounts = connections.flatMap(connection => connection.accounts.map(({ address }) => CoreHelperUtil.createAccount(chainNamespace, address, 'eoa'))); return { allAccounts, caipAddress: chainAccountState?.caipAddress, address: CoreHelperUtil.getPlainAddress(chainAccountState?.caipAddress), isConnected: Boolean(chainAccountState?.caipAddress), status: chainAccountState?.status, embeddedWalletInfo: authConnector && activeConnectorId === ConstantsUtil.CONNECTOR_ID.AUTH ? { user: chainAccountState?.user ? { ...chainAccountState.user, /* * Getting the username from the chain controller works well for social logins, * but Farcaster uses a different connection flow and doesn’t emit the username via events. * Since the username is stored in local storage before the chain controller updates, * it’s safe to use the local storage value here. */ username: StorageUtil.getConnectedSocialUsername() } : undefined, authProvider: chainAccountState?.socialProvider || 'email', accountType: chainAccountState?.preferredAccountType, isSmartAccountDeployed: Boolean(chainAccountState?.smartAccountDeployed) } : undefined }; } export function useDisconnect() { async function disconnect(props) { await ConnectionController.disconnect(props); } return { disconnect }; } export function useAppKitConnections(namespace) { // Snapshots to trigger re-renders on state changes useSnapshot(ConnectionController.state); useSnapshot(ConnectorController.state); useSnapshot(AssetController.state); const { activeChain } = useSnapshot(ChainController.state); const { remoteFeatures } = useSnapshot(OptionsController.state); const chainNamespace = namespace ?? activeChain; const isMultiWalletEnabled = Boolean(remoteFeatures?.multiWallet); if (!chainNamespace) { throw new Error('No namespace found'); } if (!isMultiWalletEnabled) { AlertController.open(ConstantsUtil.REMOTE_FEATURES_ALERTS.MULTI_WALLET_NOT_ENABLED.CONNECTIONS_HOOK, 'info'); return { connections: [], recentConnections: [] }; } const { connections, recentConnections } = ConnectionControllerUtil.getConnectionsData(chainNamespace); const formatConnection = useCallback((connection) => { const connector = ConnectorController.getConnectorById(connection.connectorId); const name = ConnectorController.getConnectorName(connector?.name); const icon = AssetUtil.getConnectorImage(connector); const networkImage = AssetUtil.getNetworkImage(connection.caipNetwork); return { name, icon, networkIcon: networkImage, ...connection }; }, []); return { connections: connections.map(formatConnection), recentConnections: recentConnections.map(formatConnection) }; } export function useAppKitConnection({ namespace, onSuccess, onError }) { const { connections, isSwitchingConnection } = useSnapshot(ConnectionController.state); const { activeConnectorIds } = useSnapshot(ConnectorController.state); const { activeChain } = useSnapshot(ChainController.state); const { remoteFeatures } = useSnapshot(OptionsController.state); const chainNamespace = namespace ?? activeChain; if (!chainNamespace) { throw new Error('No namespace found'); } const isMultiWalletEnabled = Boolean(remoteFeatures?.multiWallet); if (!isMultiWalletEnabled) { AlertController.open(ConstantsUtil.REMOTE_FEATURES_ALERTS.MULTI_WALLET_NOT_ENABLED.CONNECTION_HOOK, 'info'); return { connection: undefined, isPending: false, switchConnection: () => Promise.resolve(undefined), deleteConnection: () => ({}) }; } const connectorId = activeConnectorIds[chainNamespace]; const connList = connections.get(chainNamespace); const connection = connList?.find(c => c.connectorId.toLowerCase() === connectorId?.toLowerCase()); const switchConnection = useCallback(async ({ connection: _connection, address }) => { try { ConnectionController.setIsSwitchingConnection(true); await ConnectionController.switchConnection({ connection: _connection, address, namespace: chainNamespace, onChange({ address: newAddress, namespace: newNamespace, hasSwitchedAccount, hasSwitchedWallet }) { onSuccess?.({ address: newAddress, namespace: newNamespace, hasSwitchedAccount, hasSwitchedWallet, hasDeletedWallet: false }); } }); } catch (err) { const error = err instanceof Error ? err : new Error('Something went wrong'); onError?.(error); } finally { ConnectionController.setIsSwitchingConnection(false); } }, [chainNamespace, onSuccess, onError]); const deleteConnection = useCallback(({ address, connectorId }) => { StorageUtil.deleteAddressFromConnection({ connectorId, address, namespace: chainNamespace }); ConnectionController.syncStorageConnections(); onSuccess?.({ address, namespace: chainNamespace, hasSwitchedAccount: false, hasSwitchedWallet: false, hasDeletedWallet: true }); }, [chainNamespace]); return { connection, isPending: isSwitchingConnection, switchConnection, deleteConnection }; } //# sourceMappingURL=react.js.map