@lifi/wallet-management
Version:
LI.FI Wallet Management solution.
120 lines • 8.72 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { ChainType } from '@lifi/sdk';
import { ArrowBack, Close } from '@mui/icons-material';
import { Avatar, Box, Collapse, DialogContent, DialogTitle, Fade, IconButton, List, ListItemAvatar, Typography, } from '@mui/material';
import { useReducer, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useCombinedWallets } from '../hooks/useCombinedWallets.js';
import { EVMListItemButton } from './EVMListItemButton.js';
import { ListItemButton } from './ListItemButton.js';
import { ListItemText } from './ListItemText.js';
import { SVMListItemButton } from './SVMListItemButton.js';
import { UTXOListItemButton } from './UTXOListItemButton.js';
import { WalletMenuContentEmpty } from './WalletMenuContentEmpty.js';
function reducer(state, action) {
switch (action.type) {
case 'SHOW_WALLET_LIST':
return { ...state, view: 'wallet-list' };
case 'SHOW_MULTI_ECOSYSTEM':
return { view: 'multi-ecosystem', selectedWalletId: action.id };
case 'SHOW_CONNECTING':
return { view: 'connecting', selectedWalletId: action.id };
case 'HANDLE_ERROR':
if (action.error?.message?.includes('pending')) {
return { view: 'connecting', selectedWalletId: action.id };
}
return { view: 'wallet-list', selectedWalletId: action.id };
default:
return state;
}
}
export const WalletMenuContent = ({ onClose, }) => {
const { t } = useTranslation();
const { installedWallets } = useCombinedWallets();
const selectedWalletRef = useRef(null);
const [state, dispatch] = useReducer(reducer, { view: 'wallet-list' });
const handleMultiEcosystem = (id) => {
dispatch({ type: 'SHOW_MULTI_ECOSYSTEM', id });
};
const handleConnecting = (id) => {
dispatch({ type: 'SHOW_CONNECTING', id });
};
const handleBack = () => {
dispatch({ type: 'SHOW_WALLET_LIST' });
};
const handleError = (id, error) => {
dispatch({ type: 'HANDLE_ERROR', id, error });
};
const isMultiEcosystem = state.view === 'multi-ecosystem';
const isConnecting = state.view === 'connecting';
// We need to preserve selectedWallet between re-renders to avoid empty state once wallet is connected
let selectedWallet = state.selectedWalletId
? installedWallets.find((wallet) => wallet.id === state.selectedWalletId)
: null;
selectedWalletRef.current = selectedWallet || selectedWalletRef.current;
selectedWallet = selectedWalletRef.current;
const getWalletButton = (id, name, chainType, connector, ecosystemSelection) => {
const key = `${name}${ecosystemSelection ? `-${chainType}` : ''}`;
switch (chainType) {
case ChainType.UTXO:
return (_jsx(UTXOListItemButton, { ecosystemSelection: ecosystemSelection, connector: connector, onConnected: onClose, onConnecting: () => handleConnecting(id), onError: (error) => handleError(id, error) }, key));
case ChainType.EVM:
return (_jsx(EVMListItemButton, { ecosystemSelection: ecosystemSelection, connector: connector, onConnected: onClose, onConnecting: () => handleConnecting(id), onError: (error) => handleError(id, error) }, key));
case ChainType.SVM:
return (_jsx(SVMListItemButton, { ecosystemSelection: ecosystemSelection, walletAdapter: connector, onConnected: onClose, onConnecting: () => handleConnecting(id), onError: (error) => handleError(id, error) }, key));
default:
return null;
}
};
return (_jsxs(_Fragment, { children: [_jsxs(DialogTitle, { sx: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: 2,
}, children: [isMultiEcosystem || isConnecting ? (_jsx(IconButton, { onClick: handleBack, children: _jsx(ArrowBack, {}) })) : (_jsx(Box, { sx: {
height: 40,
width: 40,
} })), _jsx(Typography, { sx: {
fontWeight: 700,
margin: 'auto',
}, children: isMultiEcosystem
? t('title.selectEcosystem')
: isConnecting
? t('title.connecting')
: t('title.connectWallet') }), _jsx(IconButton, { onClick: onClose, children: _jsx(Close, {}) })] }), _jsxs(DialogContent, { sx: { padding: 2 }, children: [_jsx(Collapse, { in: state.view === 'wallet-list', timeout: { appear: 225, enter: 225, exit: 225 }, children: _jsx(Fade, { in: state.view === 'wallet-list', timeout: { appear: 225, enter: 100, exit: 225 }, children: _jsxs(List, { sx: { padding: 0 }, children: [installedWallets.map(({ id, name, icon, connectors }) => {
if (connectors.length === 1) {
const { chainType, connector } = connectors[0];
return getWalletButton(id, name, chainType, connector);
}
return (_jsxs(ListItemButton, { onClick: () => handleMultiEcosystem(id), children: [_jsx(ListItemAvatar, { children: _jsx(Avatar, { src: icon, alt: name, children: name[0] }) }), _jsx(ListItemText, { primary: name })] }, name));
}), !installedWallets.length ? _jsx(WalletMenuContentEmpty, {}) : null] }) }) }), _jsx(Collapse, { in: state.view === 'multi-ecosystem', timeout: { appear: 225, enter: 225, exit: 225 }, children: _jsx(Fade, { in: state.view === 'multi-ecosystem', timeout: { appear: 225, enter: 225, exit: 100 }, children: _jsxs(List, { sx: { padding: 0 }, children: [_jsxs(Box, { sx: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
px: 1,
pb: 2,
}, children: [_jsx(Avatar, { src: selectedWallet?.icon, alt: selectedWallet?.name, sx: { width: 80, height: 80 }, children: selectedWallet?.name[0] }), _jsx(Typography, { variant: "body2", sx: {
pt: 2,
textAlign: 'center',
}, children: t('message.multipleEcosystems', {
walletName: selectedWallet?.name,
}) })] }), selectedWallet?.connectors.map(({ chainType, connector }) => getWalletButton(state.selectedWalletId, selectedWallet?.name, chainType, connector, true))] }) }) }), _jsx(Collapse, { in: state.view === 'connecting', timeout: { appear: 225, enter: 225, exit: 225 }, children: _jsx(Fade, { in: state.view === 'connecting', timeout: { appear: 225, enter: 225, exit: 100 }, children: _jsx(List, { sx: { padding: 0 }, children: _jsxs(Box, { sx: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
px: 1,
pb: 2,
}, children: [_jsx(Avatar, { src: selectedWallet?.icon, alt: selectedWallet?.name, sx: { width: 80, height: 80 }, children: selectedWallet?.name[0] }), _jsx(Typography, { sx: {
pt: 2,
textAlign: 'center',
fontWeight: 500,
}, children: t('title.waitingForWallet', {
walletName: selectedWallet?.name,
}) }), _jsx(Typography, { variant: "body2", sx: {
pt: 2,
textAlign: 'center',
}, children: t('message.connecting') })] }) }) }) })] })] }));
};
//# sourceMappingURL=WalletMenuContent.js.map