Skip to content

Commit

Permalink
fix: activate any wallet when none is active
Browse files Browse the repository at this point in the history
in order to recover from wallet activation bugs
for example, a crash after wallet deactivation but before
activating another wallet

fix: do not explicitly deactivate wallet when switching to another

explicitly deactivating will trigger a recovery mechanism
that will activate any wallet
  • Loading branch information
mkazlauskas committed Dec 17, 2024
1 parent ed01c97 commit 66a958b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 27 deletions.
67 changes: 42 additions & 25 deletions apps/browser-extension-wallet/src/hooks/useWalletManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ const connectHardwareWalletRevamped = async (usbDevice: USBDevice): Promise<Wall
// eslint-disable-next-line max-statements
export const useWalletManager = (): UseWalletManager => {
const {
deletingWallet,
walletLock,
setWalletLock,
cardanoWallet,
Expand Down Expand Up @@ -406,6 +407,42 @@ export const useWalletManager = (): UseWalletManager => {
return firstValueFrom(walletRepository.wallets$);
}, [resetWalletLock, backgroundService, setCardanoWallet, setWalletLock, getCurrentChainId]);

const activateWallet = useCallback(
async (props: ActivateWalletProps): Promise<void> => {
const [wallets, activeWallet] = await firstValueFrom(
combineLatest([walletRepository.wallets$, walletManager.activeWalletId$])
);
if (activeWallet?.walletId === props.walletId && activeWallet?.accountIndex === props.accountIndex) {
logger.debug('Wallet is already active');
return;
}
const updateWalletMetadataProps = {
walletId: props.walletId,
metadata: {
...wallets.find(({ walletId }) => walletId === props.walletId).metadata,
lastActiveAccountIndex: props.accountIndex
}
};
await walletRepository.updateWalletMetadata(updateWalletMetadataProps);
await walletManager.activate({
...props,
chainId: getCurrentChainId()
});
},
[getCurrentChainId]
);

const activateAnyWallet = useCallback(
async (wallets: AnyWallet<Wallet.WalletMetadata, Wallet.AccountMetadata>[]) => {
const anyWallet: ActivateWalletProps = {
walletId: wallets[0].walletId,
accountIndex: wallets[0].type === WalletType.Script ? undefined : wallets[0].accounts[0]?.accountIndex
};
await activateWallet(anyWallet);
},
[activateWallet]
);

/**
* Loads wallet from storage.
* @returns resolves with wallet information or null when no wallet is found
Expand All @@ -427,6 +464,9 @@ export const useWalletManager = (): UseWalletManager => {
// If there is no active wallet, activate the 1st one
if (!activeWalletProps) {
// deleting a wallet calls deactivateWallet(): do nothing, wallet will also be deleted from repository
if (!deletingWallet) {
await activateAnyWallet(wallets);
}
return;
}

Expand Down Expand Up @@ -484,6 +524,8 @@ export const useWalletManager = (): UseWalletManager => {
cardanoWallet,
currentChain,
manageAccountsWallet,
activateAnyWallet,
deletingWallet,
setCardanoCoin,
setManageAccountsWallet
]
Expand Down Expand Up @@ -612,31 +654,6 @@ export const useWalletManager = (): UseWalletManager => {
return createWallet({ name, passphrase, metadata, encryptedSecrets, extendedAccountPublicKey });
};

const activateWallet = useCallback(
async (props: ActivateWalletProps): Promise<void> => {
const [wallets, activeWallet] = await firstValueFrom(
combineLatest([walletRepository.wallets$, walletManager.activeWalletId$])
);
if (activeWallet?.walletId === props.walletId && activeWallet?.accountIndex === props.accountIndex) {
logger.debug('Wallet is already active');
return;
}
await walletManager.deactivate();
await walletRepository.updateWalletMetadata({
walletId: props.walletId,
metadata: {
...wallets.find(({ walletId }) => walletId === props.walletId).metadata,
lastActiveAccountIndex: props.accountIndex
}
});
await walletManager.activate({
...props,
chainId: getCurrentChainId()
});
},
[getCurrentChainId]
);

/**
* Deletes Wallet from memory, all info from browser storage and destroys all stores
*
Expand Down
5 changes: 3 additions & 2 deletions packages/e2e-tests/src/fixture/walletRepositoryInitializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ export const clearWalletRepository = async (): Promise<void> => {
await switchToWindowWithLace(0);
await browser.execute(`
return (async () => {
await window.walletManager.deactivate();
const wallets = await window.firstValueFrom(window.walletRepository.wallets$);
for (const wallet of wallets) {
// reversing in order to delete shared wallets before dependent wallets
for (const wallet of wallets.reverse()) {
await window.walletRepository.removeWallet(wallet.walletId);
}
await window.walletManager.deactivate();
return JSON.stringify(wallets);
})()
`);
Expand Down

0 comments on commit 66a958b

Please sign in to comment.