Skip to content
Permalink
Browse files

Merge pull request #770 from Emurgo/v_almonacid/ch2689/warn-users-wit…

…h-flawed-wallets

add warning modal for debug wallets
  • Loading branch information
nicarq committed Feb 14, 2020
2 parents ddbd26d + 325adbc commit 6a37478ad99a2c61c762d987d8dc609e1848262a
@@ -485,3 +485,20 @@ export const submitShelleyTx = (encodedTx: Uint8Array) => async (
// but this action updates the wallet state
dispatch(updateHistory())
}

export const checkForFlawedWallets = () => async (dispatch: Dispatch<any>) => {
let isFlawed = false
Logger.debug('actions::checkForFlawedWallets:: checking wallet...')
try {
isFlawed = await walletManager.checkForFlawedWallets()
Logger.debug('actions::checkForFlawedWallets::isFlawed', isFlawed)
dispatch({
path: ['isFlawedWallet'],
payload: isFlawed,
reducer: (state, isFlawed) => isFlawed,
type: 'SET_FLAWED_WALLET',
})
} catch (e) {
Logger.warn('actions::checkForFlawedWallets error', e)
}
}
@@ -30,6 +30,7 @@ import {
isFetchingPoolInfoSelector,
totalDelegatedSelector,
lastAccountStateFetchErrorSelector,
isFlawedWalletSelector,
} from '../../selectors'
import DelegationNavigationButtons from './DelegationNavigationButtons'
import UtxoAutoRefresher from '../Send/UtxoAutoRefresher'
@@ -44,10 +45,12 @@ import {
import {fetchAccountState} from '../../actions/account'
import {fetchUTXOs} from '../../actions/utxo'
import {fetchPoolInfo} from '../../actions/pools'
import {SHELLEY_WALLET_ROUTES} from '../../RoutesList'
import {checkForFlawedWallets} from '../../actions'
import {SHELLEY_WALLET_ROUTES, WALLET_INIT_ROUTES} from '../../RoutesList'
import walletManager from '../../crypto/wallet'
import globalMessages from '../../i18n/global-messages'
import {formatAdaWithText, formatAdaInteger} from '../../utils/format'
import FlawedWalletModal from '../TxHistory/FlawedWalletModal'

import styles from './styles/DelegationSummary.style'

@@ -85,6 +88,8 @@ type Props = {
poolInfo: ?RemotePoolMetaSuccess,
totalDelegated: BigNumber,
lastAccountStateSyncError: any,
checkForFlawedWallets: () => any,
isFlawedWallet: boolean,
}

type State = {
@@ -108,6 +113,7 @@ class DelegationSummary extends React.Component<Props, State> {
1000,
)
this.props.fetchPoolInfo()
this.props.checkForFlawedWallets()
}

componentDidUpdate(prevProps) {
@@ -181,6 +187,8 @@ class DelegationSummary extends React.Component<Props, State> {
lastAccountStateSyncError,
isFetchingUtxos,
intl,
isFlawedWallet,
navigation,
} = this.props

const totalBalance =
@@ -214,6 +222,21 @@ class DelegationSummary extends React.Component<Props, State> {
return num.toString()
}

if (isFlawedWallet === true) {
return (
<FlawedWalletModal
visible
disableButtons={false}
onPress={() =>
navigation.navigate(WALLET_INIT_ROUTES.WALLET_SELECTION)
}
onRequestClose={() =>
navigation.navigate(WALLET_INIT_ROUTES.WALLET_SELECTION)
}
/>
)
}

return (
<SafeAreaView style={styles.scrollView}>
<StatusBar type="dark" />
@@ -339,11 +362,13 @@ export default injectIntl(
totalDelegated: totalDelegatedSelector(state),
isOnline: isOnlineSelector(state),
walletName: walletNameSelector(state),
isFlawedWallet: isFlawedWalletSelector(state),
}),
{
fetchPoolInfo,
fetchAccountState,
fetchUTXOs,
checkForFlawedWallets,
},
),
withNavigation,
@@ -0,0 +1,86 @@
// @flow

import React from 'react'
import {View, ScrollView, Image} from 'react-native'
import {injectIntl, defineMessages, intlShape} from 'react-intl'

import {Text, Button, Modal} from '../UiKit'

import styles from './styles/FlawedWalletModal.style'
// import image from '../../assets/img/alert-circle@3x.png'
import image from '../../assets/img/mnemonic_explanation.png'

import type {ComponentType} from 'react'

const messages = defineMessages({
title: {
id: 'components.txhistory.flawedwalletmodal.title',
defaultMessage: '!!!WARNING',
},
explanation1: {
id: 'components.txhistory.flawedwalletmodal.explanation1',
defaultMessage:
'!!!It looks like you have accidentally created or restored a wallet ' +
'that is only included in special versions for development. ' +
'As a security mesure, we have disabled this wallet.',
},
explanation2: {
id: 'components.txhistory.flawedwalletmodal.explanation2',
defaultMessage:
'!!!You still can create a new wallet or restore one without restrictions. ' +
'If you were affected in some way by this issue, please contact Emurgo.',
},
okButton: {
id: 'components.txhistory.flawedwalletmodal.okButton',
defaultMessage: '!!!I understand',
},
})

type Props = {
intl: intlShape,
visible: boolean,
onPress: () => any,
onRequestClose: () => any,
disableButtons: boolean,
}

const FlawedWalletModal = ({
intl,
visible,
onPress,
onRequestClose,
disableButtons,
}: Props) => {
return (
<Modal visible={visible} onRequestClose={onRequestClose}>
<ScrollView style={styles.scrollView}>
<View style={styles.content}>
<View style={styles.heading}>
<Text style={styles.title}>
{intl.formatMessage(messages.title)}
</Text>
<Image source={image} />
</View>
<Text style={styles.paragraph}>
{intl.formatMessage(messages.explanation1)}
</Text>
<Text style={styles.paragraph}>
{intl.formatMessage(messages.explanation2)}
</Text>
</View>
<View style={styles.buttons}>
<Button
block
outlineShelley
onPress={onPress}
title={intl.formatMessage(messages.okButton)}
style={styles.button}
disabled={disableButtons}
/>
</View>
</ScrollView>
</Modal>
)
}

export default injectIntl((FlawedWalletModal: ComponentType<Props>))
@@ -18,15 +18,19 @@ import {
availableAmountSelector,
walletNameSelector,
languageSelector,
isFlawedWalletSelector,
} from '../../selectors'
import TxHistoryList from './TxHistoryList'
import TxNavigationButtons from './TxNavigationButtons'
import {updateHistory} from '../../actions/history'
import {checkForFlawedWallets} from '../../actions'
import {
onDidMount,
requireInitializedWallet,
withNavigationTitle,
} from '../../utils/renderUtils'
import FlawedWalletModal from './FlawedWalletModal'
import {WALLET_INIT_ROUTES} from '../../RoutesList'

import {formatAdaWithText} from '../../utils/format'
import image from '../../assets/img/no_transactions.png'
@@ -81,10 +85,19 @@ const TxHistory = ({
updateHistory,
lastSyncError,
availableAmount,
isFlawedWallet,
}) => (
<SafeAreaView style={styles.scrollView}>
<StatusBar type="dark" />
<View style={styles.container}>
<FlawedWalletModal
visible={isFlawedWallet === true}
disableButtons={false}
onPress={() => navigation.navigate(WALLET_INIT_ROUTES.WALLET_SELECTION)}
onRequestClose={() =>
navigation.navigate(WALLET_INIT_ROUTES.WALLET_SELECTION)
}
/>
<OfflineBanner />
{isOnline &&
lastSyncError && <SyncErrorBanner showRefresh={!isSyncing} />}
@@ -129,12 +142,15 @@ export default injectIntl(
availableAmount: availableAmountSelector(state),
walletName: walletNameSelector(state),
key: languageSelector(state),
isFlawedWallet: isFlawedWalletSelector(state),
}),
{
updateHistory,
checkForFlawedWallets,
},
),
onDidMount(({updateHistory}) => {
onDidMount(({updateHistory, checkForFlawedWallets}) => {
checkForFlawedWallets()
updateHistory()
}),
withNavigationTitle(({walletName}) => walletName),
@@ -0,0 +1,37 @@
// @flow
import {StyleSheet} from 'react-native'

import {spacing} from '../../../styles/config'

export default StyleSheet.create({
scrollView: {
paddingRight: 10,
},
paragraph: {
marginBottom: spacing.paragraphBottomMargin,
fontSize: 14,
lineHeight: 22,
},
content: {
flex: 1,
marginBottom: 24,
},
heading: {
alignItems: 'center',
justifyContent: 'center',
marginBottom: spacing.paragraphBottomMargin,
},
title: {
fontSize: 20,
lineHeight: 22,
fontWeight: 'bold',
marginBottom: spacing.paragraphBottomMargin,
},
buttons: {
flexDirection: 'row',
marginTop: 12,
},
button: {
marginHorizontal: 10,
},
})
@@ -1172,6 +1172,44 @@ class WalletManager {
: CONFIG.CARDANO
return await api.getPoolInfo(pool, config)
}

async checkForFlawedWallets(): Promise<boolean> {
const mnemonics = [CONFIG.DEBUG.MNEMONIC1, CONFIG.DEBUG.MNEMONIC2]
let affected = false
for (const mnemonic of mnemonics) {
Logger.debug('WalletManager::checkForFlawedWallets mnemonic:', mnemonic)
let flawedAddresses
if (this.isShelley) {
const flawedAddressesBech32 = await shelleyUtil.getGroupAddressesFromMnemonics(
mnemonic,
'External',
[0],
)
flawedAddresses = await Promise.all(
flawedAddressesBech32.map(async (addr) => {
return Buffer.from(
await (await Address.from_string(addr)).as_bytes(),
).toString('hex')
}),
)
} else {
flawedAddresses = await util.getAddressesFromMnemonics(
mnemonic,
'External',
[0],
CARDANO_CONFIG.MAINNET,
)
}
if (this._wallet == null) throw new WalletClosed()
if (this._wallet._externalChain.isMyAddress(flawedAddresses[0])) {
Logger.debug('WalletManager::checkForFlawedWallets: address match')
affected = true
return affected
}
}
Logger.debug('WalletManager::checkForFlawedWallets:: no match')
return affected
}
}

export default new WalletManager()
@@ -151,6 +151,10 @@
"components.stakingcenter.confirmDelegation.title": "Confirm delegation",
"components.stakingcenter.title": "Staking Center",
"components.stakingcenter.delegationTxBuildError": "Error while building delegation transaction",
"components.txhistory.flawedwalletmodal.title": "Warning",
"components.txhistory.flawedwalletmodal.explanation1": "It looks like you have accidentally created or restored a wallet that is only included in special versions for development. As a security mesure, we have disabled this wallet.",
"components.txhistory.flawedwalletmodal.explanation2": "You still can create a new wallet or restore one without restrictions. If you were affected in some way by this issue, please contact Emurgo.",
"components.txhistory.flawedwalletmodal.okButton": "I understand",
"components.txhistory.txdetails.addressPrefixChange": "/change",
"components.txhistory.txdetails.addressPrefixNotMine": "not mine",
"components.txhistory.txdetails.addressPrefixReceive": "/{idx}",
@@ -178,3 +178,6 @@ export const languageSelector = (state: State): string =>

export const isKeyboardOpenSelector = (state: State): boolean =>
state.isKeyboardOpen

export const isFlawedWalletSelector = (state: State): boolean =>
state.isFlawedWallet
@@ -61,6 +61,9 @@ export type State = {
sendCrashReports: boolean,
canEnableBiometricEncryption: boolean,
},
// need to add as a non-wallet-specific property to avoid conflict with other
// actions that may override this property (otherwise more refactoring is needed)
isFlawedWallet: boolean,
}

export const getInitialState = (): State => ({
@@ -118,6 +121,7 @@ export const getInitialState = (): State => ({
sendCrashReports: false,
canEnableBiometricEncryption: false,
},
isFlawedWallet: false,
})

export default getInitialState

0 comments on commit 6a37478

Please sign in to comment.
You can’t perform that action at this time.