@dynamic-labs/sdk-react-core
Version:
A React SDK for implementing wallet web3 authentication and authorization to your website.
120 lines (117 loc) • 5.87 kB
JavaScript
'use client'
import { __awaiter } from '../../../../../_virtual/_tslib.js';
import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
import { DynamicError } from '@dynamic-labs/utils';
import { isEmailWalletConnector } from '@dynamic-labs/wallet-connector-core';
import { useInternalUserWallets } from '../../../context/UserWalletsContext/UserWalletsContext.js';
import '@dynamic-labs/sdk-api-core';
import { logger } from '../../../shared/logger.js';
import '@dynamic-labs/iconic';
import 'react/jsx-runtime';
import '../../../context/ViewContext/ViewContext.js';
import '@dynamic-labs/wallet-book';
import '../../constants/colors.js';
import '../../constants/values.js';
import '../../../shared/consts/index.js';
import { dynamicEvents } from '../../../events/dynamicEvents.js';
import '@dynamic-labs/multi-wallet';
import 'react-international-phone';
import '../../../store/state/nonce/nonce.js';
import '../../../store/state/projectSettings/projectSettings.js';
import { updatePrimaryWalletId } from '../../functions/updatePrimaryWalletId/updatePrimaryWalletId.js';
import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
import '../../../store/state/dynamicContextProps/dynamicContextProps.js';
import '../../../store/state/primaryWalletId/primaryWalletId.js';
import { createLinkedWalletsFromWalletOptions } from './utils/createLinkedWalletsFromWalletOptions/createLinkedWalletsFromWalletOptions.js';
import { updateUserWalletsFromLinkedWallets } from './utils/updateUserWalletsFromLinkedWallets/updateUserWalletsFromLinkedWallets.js';
const useWalletConnectors = ({ connectedWallets, walletConnectorOptions, setMultiWalletWidgetState, primaryWalletId, user, canHaveMultipleWalletsConnected, separateSmartWalletAndSigner = false, }) => {
const [showQrcodeModal, setShowQrcodeModal] = useState(false);
// keeps track of the last primary wallet id to avoid emitting the same event multiple times
const lastPrimaryWalletId = useRef(primaryWalletId);
const linkedWallets = useMemo(() => {
if (!user) {
return [];
}
return createLinkedWalletsFromWalletOptions({
primaryWalletId,
separateSmartWalletAndSigner,
user,
walletConnectorOptions,
});
}, [
user,
primaryWalletId,
walletConnectorOptions,
separateSmartWalletAndSigner,
]);
logger.logVerboseTroubleshootingMessage('linkedWallets', linkedWallets);
const wallets = useMemo(() => {
if (user) {
return linkedWallets;
}
// This is to handle users in connect-only who have not yet connected a wallet
return connectedWallets !== null && connectedWallets !== void 0 ? connectedWallets : [];
}, [connectedWallets, linkedWallets, user]);
logger.logVerboseTroubleshootingMessage('wallets', wallets);
/**
* This useEffect is temporary.
* While the wallet connectors don't use the event emitter, we need to manually
* initialize the bridge between the old event listeners and the new event emitter.
* When the wallet connectors are migrated to the new event emitter, there will be no
* need to initialize or teardown event listeners, then we can remove this useEffect.
*/
useEffect(() => wallets.forEach((wallet) => {
wallet.connector.initEventListener();
}), [wallets]);
const { setUserWallets } = useInternalUserWallets();
// Keep userWallets in sync whenever linkedWallets changes
useEffect(() => {
logger.logVerboseTroubleshootingMessage('[useWalletConnectors] will call setUserWallets', wallets);
setUserWallets((userWallets) => updateUserWalletsFromLinkedWallets(userWallets, wallets));
}, [setUserWallets, wallets]);
const primaryWallet = useMemo(() => { var _a; return (_a = wallets.find((wallet) => wallet.id === primaryWalletId)) !== null && _a !== void 0 ? _a : null; }, [primaryWalletId, wallets]);
// emit primaryWalletChanged event if the primary wallet changes
useEffect(() => {
if (primaryWallet && primaryWallet.id !== lastPrimaryWalletId.current) {
lastPrimaryWalletId.current = primaryWallet.id;
dynamicEvents.emit('primaryWalletChanged', primaryWallet);
}
}, [primaryWallet]);
const secondaryWallets = useMemo(() => canHaveMultipleWalletsConnected
? wallets.filter((wallet) => wallet.id !== primaryWalletId)
: [], [primaryWalletId, wallets, canHaveMultipleWalletsConnected]);
const getSelectedWallet = useCallback((walletId) => __awaiter(void 0, void 0, void 0, function* () {
const newWallet = wallets.find(({ id }) => id === walletId);
if (!newWallet) {
throw new DynamicError(`Wallet with id: ${walletId} not found`);
}
return newWallet;
}), [wallets]);
const setPrimaryWallet = useCallback((walletId) => __awaiter(void 0, void 0, void 0, function* () {
const newPrimaryWallet = yield getSelectedWallet(walletId);
if (!primaryWalletId) {
updatePrimaryWalletId(walletId);
return;
}
if (primaryWalletId === walletId)
return;
if (isEmailWalletConnector(newPrimaryWallet.connector)) {
const emailConnector = newPrimaryWallet.connector;
const email = localStorage.getItem('magic-link-email');
if (email) {
emailConnector.setEmail(email);
}
}
updatePrimaryWalletId(walletId);
setMultiWalletWidgetState('idle');
}), [getSelectedWallet, primaryWalletId, setMultiWalletWidgetState]);
return {
primaryWallet,
secondaryWallets,
setPrimaryWallet,
setShowQrcodeModal,
showQrcodeModal,
wallets,
};
};
export { useWalletConnectors };