8000 fix regressions in create wallet and import wallet flows by natew · Pull Request #6709 · rainbow-me/rainbow · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix regressions in create wallet and import wallet flows #6709

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

Open
wants to merge 53 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
bc1ee59
add debug helper for createRainbowStore
natew Jun 24, 2025
96a88fe
natew Jun 24, 2025
379f6c1
fix regressions in create wallet and import wallet flows
natew Jun 25, 2025
fdcbea8
natew Jun 25, 2025
c126f14
natew Jun 25, 2025
9a12c5d
natew Jun 25, 2025
88111f7
natew Jun 25, 2025
045dd31
Merge branch 'nate/debug-store' into nate/wallet-part-4
natew Jun 25, 2025
4ce72c4
natew Jun 25, 2025
443e63b
natew Jun 25, 2025
c575a96
natew Jun 25, 2025
06e0c66
natew Jun 25, 2025
ccd6884
natew Jun 25, 2025
2f372fb
natew Jun 25, 2025
7e50939
fix waiting for updateWallets on restore before setting selected
natew Jun 25, 2025
499a7e5
improve wallet restore logic
natew Jun 25, 2025
8ef609c
natew Jun 25, 2025
a10f031
natew Jun 25, 2025
b7f582d
natew Jun 25, 2025
86287b0
natew Jun 25, 2025
6455a5c
natew Jun 25, 2025
910206c
natew Jun 25, 2025
4c0be6a
natew Jun 26, 2025
b79a947
natew Jun 26, 2025
7848e2f
natew Jun 26, 2025
dfedb60
natew Jun 26, 2025
264a887
natew Jun 26, 2025
227d20b
natew Jun 26, 2025
762eeba
natew Jun 26, 2025
d14017f
natew Jun 26, 2025
35e69c4
natew Jun 26, 2025
11e8d00
natew Jun 26, 2025
70124ee
natew Jun 26, 2025
d1f13b2
natew Jun 26, 2025
6c40fbf
natew Jun 26, 2025
53b47b3
natew Jun 26, 2025
7b5c19e
natew Jun 26, 2025
19185ad
natew Jun 26, 2025
d10d197
natew Jun 26, 2025
c751dbf
natew Jun 26, 2025
bb84460
natew Jun 26, 2025
7b360c5
natew Jun 26, 2025
69aae76
natew Jun 26, 2025
fb50373
natew Jun 26, 2025
6315ee7
natew Jun 26, 2025
ae23889
natew Jun 26, 2025
e88e641
natew Jun 26, 2025
ff1309 8000 0
natew Jun 26, 2025
b899bdc
natew Jun 26, 2025
3cf9b96
natew Jun 26, 2025
df6166c
natew Jun 26, 2025
5ea2be4
natew Jun 26, 2025
8c4b8b5
natew Jun 26, 2025
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
4 changes: 2 additions & 2 deletions src/components/DappBrowser/control-panel/ControlPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ const HomePanel = memo(function HomePanel({
// Check if it's different to the globally selected wallet
if (selectedWallet.uniqueId !== accountAddress) {
// switch to selected wallet
setSelectedWallet(walletInPanel, selectedWallet.uniqueId);
initializeWallet({
await setSelectedWallet(walletInPanel, selectedWallet.uniqueId);
await initializeWallet({
shouldRunMigrations: false,
overwrite: false,
switching: true,
Expand Down
45 changes: 4 additions & 41 deletions src/components/backup/RestoreCloudStep.tsx
8000
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Box, Inset, Stack } from '@/design-system';
import { IS_ANDROID } from '@/env';
import { isCloudBackupPasswordValid, normalizeAndroidBackupFilename } from '@/handlers/cloudBackup';
import { WrappedAlert as Alert } from '@/helpers/alert';
import walletBackupTypes from '@/helpers/walletBackupTypes';
import { WalletLoadingStates } from '@/helpers/walletLoadingStates';
import { useDimensions } from '@/hooks';
import * as lang from '@/languages';
Expand All @@ -17,7 +16,7 @@ import Routes from '@/navigation/routesNames';
import { RootStackParamList } from '@/navigation/types';
import { backupsStore } from '@/state/backups/backups';
import { walletLoadingStore } from '@/state/walletLoading/walletLoading';
import { loadWallets, setAllWalletsWithIdsAsBackedUp, setSelectedWallet } from '@/state/wallets/walletsStore';
import { loadWallets } from '@/state/wallets/walletsStore';
import styled from '@/styled-thing';
import { padding } from '@/styles';
import { ThemeContextProps, useTheme } from '@/theme';
Expand All @@ -32,8 +31,8 @@ import RainbowButtonTypes from '../buttons/rainbow-button/RainbowButtonTypes';
import { PasswordField } from '../fields';
import { ImgixImage } from '../images';
import { Text } from '../text';
import { initializeWallet } from '@/state/wallets/initializeWallet';
import { maybeAuthenticateWithPIN } from '@/handlers/authentication';
import { updateWalletsBackedUpState } from '@/state/wallets/updateWalletsBackedUpState';

type ComponentProps = {
theme: ThemeContextProps;
Expand Down Expand Up @@ -140,6 +139,7 @@ export default function RestoreCloudStep() {
password: pwd,
backupFilename: filename,
});

if (status === RestoreCloudBackupResultStates.success) {
// Store it in the keychain in case it was missing
if (backupsStore.getState().storedPassword !== pwd) {
Expand All @@ -152,49 +152,12 @@ export default function RestoreCloudStep() {
}

InteractionManager.runAfterInteractions(async () => {
const newWalletsState = await loadWallets();
if (IS_ANDROID && filename) {
filename = normalizeAndroidBackupFilename(filename);
}

logger.debug('[RestoreCloudStep]: Done updating backup state');
// NOTE: Marking the restored wallets as backed up
const walletIdsToUpdate = Object.keys(newWalletsState || {}).filter(walletId => !(prevWalletsState || {})[walletId]);

logger.debug('[RestoreCloudStep]: Updating backup state of wallets with ids', {
walletIds: JSON.stringify(walletIdsToUpdate),
});
logger.debug(`[RestoreCloudStep]: Selected backup name: ${filename}`);

setAllWalletsWithIdsAsBackedUp(walletIdsToUpdate, walletBackupTypes.cloud, filename);

const oldCloudIds: string[] = [];
const oldManualIds: string[] = [];
// NOTE: Looping over previous wallets and restoring backup state of that wallet
Object.values(prevWalletsState || {}).forEach(wallet => {
// NOTE: This handles cloud and manual backups
if (wallet.backedUp && wallet.backupType === walletBackupTypes.cloud) {
oldCloudIds.push(wallet.id);
} else if (wallet.backedUp && wallet.backupType === walletBackupTypes.manual) {
oldManualIds.push(wallet.id);
}
});

setAllWalletsWithIdsAsBackedUp(oldCloudIds, walletBackupTypes.cloud, filename);
setAllWalletsWithIdsAsBackedUp(oldManualIds, walletBackupTypes.manual, filename);

const walletKeys = Object.keys(newWalletsState || {});
const firstWallet = walletKeys.length > 0 ? (newWalletsState || {})[walletKeys[0]] : undefined;
const firstAddress = firstWallet ? (firstWallet.addresses || [])[0].address : undefined;

if (firstWallet) {
setSelectedWallet(firstWallet, firstAddress);
await initializeWallet({
shouldRunMigrations: false,
overwrite: false,
switching: true,
});
}
await updateWalletsBackedUpState({ filename, prevWalletsState });
});

onRestoreSuccess();
Expand Down
30 changes: 15 additions & 15 deletions src/components/expanded-state/DevTestBackupState.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import CopyTooltip from '@/components/copy-tooltip';
import { Box, Text } from '@/design-system';
import { WalletLoadingStates } from '@/helpers/walletLoadingStates';
import { logger, RainbowError } from '@/logger';
import { createBackup, restoreBackup } from '@/model/backup';
import React, { useEffect, useState } from 'react';
import { Alert, Pressable, View } from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';
import { wipeKeychain } from '@/model/keychain';
import { clearAllStorages } from '@/model/mmkv';
import { navigate, useNavigation } from '@/navigation/Navigation';
import Routes from '@/navigation/Routes';
import { clearWalletState, loadWallets, useWalletsStore } from '@/state/wallets/walletsStore';
import { walletLoadingStore } from '@/state/walletLoading/walletLoading';
import { WalletLoadingStates } from '@/helpers/walletLoadingStates';
import { updateWalletsBackedUpState } from '@/state/wallets/updateWalletsBackedUpState';
import { clearWalletState, loadWallets } from '@/state/wallets/walletsStore';
import Clipboard from '@react-native-clipboard/clipboard';
import React, { useEffect, useState } from 'react';
import { Alert, DevSettings, Pressable, View } from 'react-native';

export const DevTestBackupState = () => {
const { goBack } = useNavigation();
const [exported, setExported] = useState('test123');

useEffect(() => {
Expand Down Expand Up @@ -58,14 +57,19 @@ export const DevTestBackupState = () => {
walletLoadingStore.setState({
loadingState: WalletLoadingStates.IMPORTING_WALLET,
});

const prevWalletsState = await loadWallets();
const restored = await restoreBackup(backup);
logger.log(`restored: ${restored}`);

if (restored) {
await loadWallets();
goBack();
await updateWalletsBackedUpState({ prevWalletsState });
DevSettings.reload();
} else {
Alert.alert(`invalid backup`);
}
} catch (err) {
logger.error(new RainbowError(`Error restoring`, err));
} finally {
walletLoadingStore.setState({
loadingState: null,
Expand Down Expand Up @@ -94,11 +98,7 @@ export const DevTestBackupState = () => {
await wipeKeychain();
await clearAllStorages();
clearWalletState();
// we need to navigate back to the welcome screen
goBack();
setTimeout(() => {
navigate(Routes.WELCOME_SCREEN);
}, 500);
DevSettings.reload();
}}
>
<Box
Expand Down
16 changes: 15 additions & 1 deletion src/hooks/useENSAvatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export const ensAvatarQueryKey = (name: string) => ['ens-avatar', name];

const STALE_TIME = 10000;

export async function fetchENSAvatar(name: string, { cacheFirst, swallowError }: { cacheFirst?: boolean; swallowError?: boolean } = {}) {
type FetchENSAvatarOptions = { cacheFirst?: boolean; swallowError?: boolean };

export async function fetchENSAvatar(name: string, { cacheFirst, swallowError }: FetchENSAvatarOptions = {}) {
try {
const cachedAvatar = await getENSData('avatar', name);
if (cachedAvatar) {
Expand All @@ -23,6 +25,18 @@ export async function fetchENSAvatar(name: string, { cacheFirst, swallowError }:
}
}

export async function fetchENSAvatarWithRetry(name: string, options: FetchENSAvatarOptions = {}) {
for (let i = 0; i < 3; i++) {
try {
return await fetchENSAvatar(name, options);
// eslint-disable-next-line no-empty
} catch (err) {
console.log('error fetching', err);
}
}
return null;
}

export async function prefetchENSAvatar(name: string, { cacheFirst }: { cacheFirst?: boolean } = {}) {
queryClient.prefetchQuery(ensAvatarQueryKey(name), async () => fetchENSAvatar(name, { cacheFirst }), { staleTime: STALE_TIME });
}
Expand Down
6 changes: 2 additions & 4 deletions src/hooks/useOnAvatarPress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ export default ({ screenType = 'transaction' }: UseOnAvatarPressProps = {}) => {
},
};

setSelectedWallet(newWallets[selectedWallet.id]);
updateWallets(newWallets);
await setSelectedWallet(newWallets[selectedWallet.id], accountAddress, newWallets);
}, [selectedWallet, accountAddress, wallets]);

const processPhoto = useCallback(
Expand All @@ -92,8 +91,7 @@ export default ({ screenType = 'transaction' }: UseOnAvatarPressProps = {}) => {
},
};

setSelectedWallet(newWallets[selectedWallet.id]);
updateWallets(newWallets);
setSelectedWallet(newWallets[selectedWallet.id], accountAddress, newWallets);
},
[accountAddress, selectedWallet, wallets]
);
Expand Down
10000
3 changes: 1 addition & 2 deletions src/hooks/useUpdateEmoji.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ export default function useUpdateEmoji() {
},
};

setSelectedWallet(newWallets[walletId]);
updateWallets(newWallets);
await setSelectedWallet(newWallets[walletId], accountAddress, newWallets);
const nextColor = color !== undefined ? colors.avatarBackgrounds[color || accountColor] : undefined;
if (nextColor) {
updateWebProfile(accountAddress, name, nextColor);
Expand Down
8 changes: 4 additions & 4 deletions src/hooks/useWalletBalances.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { add, convertAmountToNativeDisplay } from '@/helpers/utilities';
import { AllRainbowWallets } from '@/model/wallet';
import { userAssetsStoreManager } from '@/state/assets/userAssetsStoreManager';
import { useWalletSummary } from '@/state/wallets/useWalletSummaryStore';
import { getWalletAddresses, getWallets } from '@/state/wallets/walletsStore';
import { getWalletAddresses } from '@/state/wallets/walletsStore';
import { useMemo } from 'react';
import { Address } from 'viem';

Expand All @@ -24,12 +25,11 @@ export type WalletBalanceResult = {
* @param wallets - All Rainbow wallets
* @returns Balances for all wallets
*/
const useWalletBalances = (): WalletBalanceResult => {
const useWalletBalances = (wallets: AllRainbowWallets | null): WalletBalanceResult => {
const summaryData = useWalletSummary();

const balances = useMemo(() => {
const result: Record<Address, WalletBalance> = {};
const wallets = getWallets();

if (!summaryData || !wallets) {
return result;
Expand Down Expand Up @@ -63,7 +63,7 @@ const useWalletBalances = (): WalletBalanceResult => {
}

return result;
}, [summaryData]);
}, [summaryData, wallets]);

return {
balances,
Expand Down
5 changes: 3 additions & 2 deletions src/hooks/useWalletsWithBalancesAndNames.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { convertAmountToNativeDisplay, subtract } from '@/helpers/utilities';
import { useWallets, useWalletsStore } from '@/state/wallets/walletsStore';
import { userAssetsStoreManager } from '@/state/assets/userAssetsStoreManager';
import { useWallets, useWalletsStore } from '@/state/wallets/walletsStore';
import mapValues from 'lodash/mapValues';
import { useMemo } from 'react';
import { Address } from 'viem';
Expand All @@ -10,14 +10,15 @@ export default function useWalletsWithBalancesAndNames() {
const nativeCurrency = userAssetsStoreManager(state => state.currency);
const walletNames = useWalletsStore(state => state.walletNames);
const wallets = useWallets();
const { balances } = useWalletBalances();
const { balances } = useWalletBalances(wallets);
const hiddenBalances = userAssetsStoreManager(state => state.hiddenAssetBalances);

const walletsWithBalancesAndNames = useMemo(
() =>
mapValues(wallets, wallet => {
const updatedAccounts = (wallet.addresses || []).map(account => {
const lowerCaseAddress = account.address.toLowerCase() as Address;

return {
...account,
balances: balances[lowerCaseAddress],
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useWatchWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export default function useWatchWallet({
async (walletId: string, address: string) => {
const wallet = (wallets || {})[walletId];
try {
setSelectedWallet(wallet, address);
initializeWallet({
await setSelectedWallet(wallet, address);
await initializeWallet({
shouldRunMigrations: false,
overwrite: false,
switching: true,
Expand Down
14 changes: 11 additions & 3 deletions src/model/backup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import * as keychain from '@/model/keychain';
import { Navigation } from '@/navigation';
import Routes from '@/navigation/routesNames';
import { backupsStore, CloudBackupState } from '@/state/backups/backups';
import { setAllWalletsWithIdsAsBackedUp } from '@/state/wallets/walletsStore';
import { loadWallets, refreshWalletInfo, setAllWalletsWithIdsAsBackedUp } from '@/state/wallets/walletsStore';
import { identifierForVendorKey, pinKey, privateKeyKey, seedPhraseKey } from '@/utils/keychainConstants';
import { openInBrowser } from '@/utils/openInBrowser';
import { cloudPlatform } from '@/utils/platform';
Expand Down Expand Up @@ -286,12 +286,19 @@ export async function restoreBackup(data: string | { secrets: string }) {
return RestoreCloudBackupResultStates.incorrectPinCode;
}

return await restoreSpecificBackupIntoKeychain(
const restored = await restoreSpecificBackupIntoKeychain(
{
...originalData.secrets,
},
userPIN
);

if (restored) {
await loadWallets();
await refreshWalletInfo();
}

return restored;
}

export async function backupWalletToCloud({
Expand Down Expand Up @@ -522,9 +529,10 @@ async function restoreSpecificBackupIntoKeychain(backedUpData: BackedUpData, use
userPin,
});
}

return true;
} catch (e) {
logger.error(new RainbowError(`[backup]: Error restoring specific backup into keychain: ${e}`));
logger.error(new RainbowError(`[backup]: Error restoring specific backup into keychain`, e));
return false;
}
}
Expand Down
9 changes: 0 additions & 9 deletions src/model/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,6 @@ export function ensureEthereumWallet(wallet: EthereumWallet): asserts wallet is
if ('signTransaction' in wallet) {
return wallet as any;
}
// TODO this is a partial fix - at least we log the error now, next is a bigger cleanup
console.log(
// @ts-expect-error using property types to log errors better
`Not expected: ReadOnly not Wallet (signTransaction: ${typeof wallet['signTransaction']}) (getPrivateKey: ${typeof wallet['getPrivateKey']})`
);
}

export function ensureLibWallet(wallet: EthereumWallet): asserts wallet is LibWallet {
Expand All @@ -205,10 +200,6 @@ export function ensureLibWallet(wallet: EthereumWallet): asserts wallet is LibWa
if (typeof wallet.getPrivateKey !== 'function') {
return wallet as any;
}
// TODO this is a partial fix - at least we log the error now, next is a bigger cleanup
console.log(
`Not expected: ReadOnly not LibWallet: ${'address' in wallet ? wallet.address : wallet.getAddressString()} ${new Error().stack}`
);
}

const isHardwareWalletKey = (key: string | null) => {
Expand Down
Loading
Loading
0