Skip to content

Commit

Permalink
Log and restore if possible while showing secret (#949)
Browse files Browse the repository at this point in the history
* log and restore keychain if needed

* add more logging for wallets
  • Loading branch information
brunobar79 authored Jul 27, 2020
1 parent b114499 commit 2bcdda0
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 8 deletions.
105 changes: 100 additions & 5 deletions src/components/settings-menu/BackupSection.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import analytics from '@segment/analytics-react-native';
import { captureMessage } from '@sentry/react-native';
import PropTypes from 'prop-types';
import React, { useCallback, useState } from 'react';
import FastImage from 'react-native-fast-image';
import styled from 'styled-components';
import SeedPhraseImageSource from '../../assets/seed-phrase-icon.png';
import { useWallets } from '../../hooks';
import { loadSeedPhraseAndMigrateIfNeeded } from '../../model/wallet';
import {
getAllWallets,
getSelectedWallet,
loadAddress,
loadSeedPhraseAndMigrateIfNeeded,
} from '../../model/wallet';
import store from '../../redux/store';
import { walletsLoadState, walletsUpdate } from '../../redux/wallets';
import { logger } from '../../utils';
import { Button } from '../buttons';
import CopyTooltip from '../copy-tooltip';
import { Centered, Column } from '../layout';
Expand All @@ -28,21 +37,107 @@ const ToggleSeedPhraseButton = styled(Button)`
const BackupSection = ({ navigation }) => {
const [seedPhrase, setSeedPhrase] = useState(null);
const { selectedWallet } = useWallets();
const [shouldRetry, setShouldRetry] = useState(true);

const hideSeedPhrase = () => setSeedPhrase(null);

const logAndAttemptRestore = useCallback(
async error => {
if (!shouldRetry) {
hideSeedPhrase();
return;
}

setShouldRetry(false);

// 1 - Log the error if exists
if (error) {
logger.sentry(
'[logAndAttemptRestore]: Error while revealing seed',
error
);
}

// 2 - Log redux and public keychain entries
logger.sentry('[logAndAttemptRestore]: REDUX DATA:', store.getState());
try {
logger.sentry(
'[logAndAttemptRestore]: Keychain allWallets:',
await getAllWallets()
);
// eslint-disable-next-line no-empty
} catch (e) {}

try {
logger.sentry(
'[logAndAttemptRestore]: Keychain selectedWallet:',
await getSelectedWallet()
);
// eslint-disable-next-line no-empty
} catch (e) {}

try {
logger.sentry(
'[logAndAttemptRestore]: Keychain address:',
await loadAddress()
);
// eslint-disable-next-line no-empty
} catch (e) {}

// 3 - Send message to sentry
captureMessage(`Error while revealing seed`);
logger.sentry('[logAndAttemptRestore] message sent to sentry');

// 4 - Attempt to restore
try {
// eslint-disable-next-line no-unused-vars
const { wallets } = await getAllWallets();
logger.sentry('[logAndAttemptRestore] Got all wallets');
} catch (e) {
logger.sentry(
'[logAndAttemptRestore] Got error getting all wallets',
e
);
// if we don't have all wallets, let's see if we have a selected wallet
const selected = await getSelectedWallet();
logger.sentry('[logAndAttemptRestore] Got selected wallet');
if (selected?.wallet?.id) {
const { wallet } = selected;
// We can recover it based in the selected wallet
await store.dispatch(walletsUpdate({ [wallet.id]: wallet }));
logger.sentry('[logAndAttemptRestore] Updated wallets');
await store.dispatch(walletsLoadState());
logger.sentry('[logAndAttemptRestore] Reloaded wallets state');
// Retrying one more time
const keychainValue = await loadSeedPhraseAndMigrateIfNeeded(
wallet.id
);
if (keychainValue) {
setSeedPhrase(keychainValue);
captureMessage(`Restore from selected wallet successful`);
}
}
}
},
[shouldRetry]
);

const handlePressToggleSeedPhrase = useCallback(() => {
if (!seedPhrase) {
loadSeedPhraseAndMigrateIfNeeded(selectedWallet.id)
.then(keychainValue => {
setSeedPhrase(keychainValue);
analytics.track('Viewed backup seed phrase text');
if (!keychainValue) {
logAndAttemptRestore();
} else {
setSeedPhrase(keychainValue);
analytics.track('Viewed backup seed phrase text');
}
})
.catch(hideSeedPhrase);
.catch(e => logAndAttemptRestore(e));
} else {
hideSeedPhrase();
}
}, [seedPhrase, selectedWallet.id]);
}, [logAndAttemptRestore, seedPhrase, selectedWallet.id]);

return (
<Column align="center" css={padding(80, 40, 0)} flex={1}>
Expand Down
16 changes: 13 additions & 3 deletions src/redux/wallets.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { captureException } from '@sentry/react-native';
import { toChecksumAddress } from 'ethereumjs-util';
import { filter, flatMap, get, map, values } from 'lodash';
import {
Expand All @@ -15,6 +16,7 @@ import {
setSelectedWallet,
} from '../model/wallet';
import { settingsUpdateAccountAddress } from '../redux/settings';
import { logger } from '../utils';

// -- Constants --------------------------------------- //
const WALLETS_ADDED_ACCOUNT = 'wallets/WALLETS_ADDED_ACCOUNT';
Expand Down Expand Up @@ -44,6 +46,7 @@ export const walletsLoadState = () => async (dispatch, getState) => {
});
if (found) {
selectedWallet = someWallet;
logger.sentry('Found selected wallet based on loadAddress result');
}
return found;
});
Expand All @@ -52,6 +55,9 @@ export const walletsLoadState = () => async (dispatch, getState) => {
// Recover from broken state (account address not in selected wallet)
if (!addressFromKeychain) {
addressFromKeychain = await loadAddress();
logger.sentry(
'addressFromKeychain wasnt set on settings so it is being loaded from loadAddress'
);
}

const selectedAddress = selectedWallet.addresses.find(a => {
Expand All @@ -62,6 +68,9 @@ export const walletsLoadState = () => async (dispatch, getState) => {
const account = selectedWallet.addresses.find(a => a.visible);
await dispatch(settingsUpdateAccountAddress(account.address));
await saveAddress(account.address);
logger.sentry(
'Selected the first visible address because there was not selected one'
);
}

const walletNames = await getWalletNames();
Expand All @@ -76,9 +85,10 @@ export const walletsLoadState = () => async (dispatch, getState) => {
});

dispatch(fetchWalletNames());

// eslint-disable-next-line no-empty
} catch (error) {}
} catch (error) {
logger.sentry('Exception during walletsLoadState');
captureException(error);
}
};

export const walletsUpdate = wallets => dispatch => {
Expand Down
3 changes: 3 additions & 0 deletions src/utils/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ const Logger = {
} else {
sentryUtils.addDataBreadcrumb.apply(null, args);
}
if (__DEV__) {
console.log(...args);
}
},
warn(...args) {
if (__DEV__) {
Expand Down

0 comments on commit 2bcdda0

Please sign in to comment.