Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically connect to previously used wallet for a given chain context #1913

Merged
merged 3 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions wormhole-connect/src/utils/wallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@ import {
Wallet,
WalletState,
} from '@xlabs-libs/wallet-aggregator-core';
import {
connectReceivingWallet,
connectWallet as connectSourceWallet,
clearWallet,
} from 'store/wallet';

import config from 'config';
import { getChainByChainId } from 'utils';

import { RootState } from 'store';
import { AssetInfo } from './evm';
import { Dispatch } from 'redux';
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';

export enum TransferWallet {
SENDING = 'sending',
Expand All @@ -44,6 +53,92 @@ export const setWalletConnection = (type: TransferWallet, wallet: Wallet) => {
walletConnection[type] = wallet;
};

export const connectWallet = async (
type: TransferWallet,
chain: ChainName,
walletInfo: WalletData,
dispatch: Dispatch<any>,
) => {
const { wallet, name } = walletInfo;

setWalletConnection(type, wallet);

const chainConfig = config.chains[chain];
if (!chainConfig) {
throw new Error(`Unable to find wallets for chain ${chain}`);
}

const { chainId, context } = chainConfig;
await wallet.connect({ chainId });
const address = wallet.getAddress()!;
const payload = {
address,
type: walletInfo.type,
icon: wallet.getIcon(),
name: wallet.getName(),
};

if (type === TransferWallet.SENDING) {
dispatch(connectSourceWallet(payload));
} else {
dispatch(connectReceivingWallet(payload));
}

// clear wallet when the user manually disconnects from outside the app
wallet.on('disconnect', () => {
wallet.removeAllListeners();
dispatch(clearWallet(type));
});

// when the user has multiple wallets connected and either changes
// or disconnects the current wallet, clear the wallet
wallet.on('accountsChanged', (accs: string[]) => {
// disconnect only if there are no accounts, or if the new account is different from the current
const shouldDisconnect =
accs.length === 0 || (accs.length && address && accs[0] !== address);

if (shouldDisconnect) {
wallet.disconnect();
}
});

localStorage.setItem(`wormhole-connect:wallet:${context}`, name);
};

// Checks localStorage for previously used wallet for this chain
// and connects to it automatically if it exists.
export const connectLastUsedWallet = async (
type: TransferWallet,
chain: ChainName,
dispatch: Dispatch<any>,
) => {
const chainConfig = config.chains[chain!]!;
const lastUsedWallet = localStorage.getItem(
`wormhole-connect:wallet:${chainConfig.context}`,
);
if (lastUsedWallet) {
const options = await getWalletOptions(chainConfig);
const wallet = options.find((w) => w.name === lastUsedWallet);
if (wallet) {
await connectWallet(type, chain, wallet, dispatch);
}
}
};

export const useConnectToLastUsedWallet = (): void => {
const dispatch = useDispatch();
const { toChain, fromChain } = useSelector(
(state: RootState) => state.transferInput,
);

useEffect(() => {
if (fromChain)
connectLastUsedWallet(TransferWallet.SENDING, fromChain, dispatch);
if (toChain)
connectLastUsedWallet(TransferWallet.RECEIVING, toChain, dispatch);
}, [fromChain, toChain]);
};

export const getWalletConnection = (type: TransferWallet) => {
return walletConnection[type];
};
Expand Down
2 changes: 2 additions & 0 deletions wormhole-connect/src/views/Bridge/Bridge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { usePorticoRelayerFee } from 'hooks/usePorticoRelayerFee';
import { useFetchTokenPrices } from 'hooks/useFetchTokenPrices';
import NttInboundCapacityWarning from './NttInboundCapacityWarning';
import { isNttRoute } from 'routes/utils';
import { useConnectToLastUsedWallet } from 'utils/wallet';

const useStyles = makeStyles()((_theme) => ({
spacer: {
Expand Down Expand Up @@ -262,6 +263,7 @@ function Bridge() {
usePorticoSwapInfo();
usePorticoRelayerFee();
useFetchTokenPrices();
useConnectToLastUsedWallet();

// validate transfer inputs
useValidate();
Expand Down
2 changes: 1 addition & 1 deletion wormhole-connect/src/views/Bridge/Inputs/From.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function FromInputs() {
);

const selectChain = async (chain: ChainName) => {
selectFromChain(dispatch, chain, wallet);
await selectFromChain(dispatch, chain, wallet);
};

const selectToken = (token: string) => {
Expand Down
2 changes: 1 addition & 1 deletion wormhole-connect/src/views/Bridge/Inputs/To.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function ToInputs() {
);

const selectChain = async (chain: ChainName) => {
selectToChain(dispatch, chain, receiving);
await selectToChain(dispatch, chain, receiving);
};

// token display jsx
Expand Down
52 changes: 4 additions & 48 deletions wormhole-connect/src/views/WalletModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@ import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk';
import config from 'config';
import { RootState } from 'store';
import { setWalletModal } from 'store/router';
import {
clearWallet,
connectReceivingWallet,
connectWallet,
} from 'store/wallet';
import {
TransferWallet,
WalletData,
getWalletOptions,
setWalletConnection,
connectWallet,
} from 'utils/wallet';
import { CENTER } from 'utils/style';

Expand Down Expand Up @@ -160,49 +155,10 @@ function WalletsModal(props: Props) {
};

const connect = async (walletInfo: WalletData) => {
const { wallet } = walletInfo;

const chain = type === TransferWallet.SENDING ? fromChain : toChain;
const chainId = chain ? config.chains[chain]?.chainId : undefined;
await wallet.connect({ chainId });

setWalletConnection(props.type, wallet);

const address = wallet.getAddress();

// clear wallet when the user manually disconnects from outside the app
wallet.on('disconnect', () => {
wallet.removeAllListeners();
dispatch(clearWallet(props.type));
});

// when the user has multiple wallets connected and either changes
// or disconnects the current wallet, clear the wallet
wallet.on('accountsChanged', (accs: string[]) => {
// disconnect only if there are no accounts, or if the new account is different from the current
const shouldDisconnect =
accs.length === 0 || (accs.length && address && accs[0] !== address);

if (shouldDisconnect) {
wallet.disconnect();
}
});

if (address) {
const payload = {
address,
type: walletInfo.type,
icon: wallet.getIcon(),
name: wallet.getName(),
};
if (props.type === TransferWallet.SENDING) {
dispatch(connectWallet(payload));
} else {
dispatch(connectReceivingWallet(payload));
}
dispatch(setWalletModal(false));
if (props.onClose) props.onClose();
}
dispatch(setWalletModal(false));
if (props.onClose) props.onClose();
await connectWallet(props.type, chain!, walletInfo, dispatch);
};

const displayWalletOptions = (wallets: WalletData[]): JSX.Element[] => {
Expand Down
Loading