Browse Source

Merge pull request #1307 from gre/debug-app-version-on-error

Add a way to get app version and log it if there is an error
master
Gaëtan Renaudeau 7 years ago
committed by GitHub
parent
commit
a1eb1fd4c4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      src/commands/debugAppInfosForCurrency.js
  2. 2
      src/commands/index.js
  3. 51
      src/components/DebugAppInfosForCurrency.js
  4. 4
      src/components/modals/AddAccounts/steps/03-step-import.js
  5. 2
      src/components/modals/Receive/steps/03-step-confirm-address.js
  6. 4
      src/components/modals/Send/steps/04-step-confirmation.js
  7. 12
      src/helpers/debugAppInfosForCurrency/btc.js
  8. 10
      src/helpers/debugAppInfosForCurrency/ethereum.js
  9. 29
      src/helpers/debugAppInfosForCurrency/index.js
  10. 10
      src/helpers/debugAppInfosForCurrency/ripple.js

28
src/commands/debugAppInfosForCurrency.js

@ -0,0 +1,28 @@
// @flow
import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/helpers/currencies'
import { createCommand, Command } from 'helpers/ipc'
import { fromPromise } from 'rxjs/observable/fromPromise'
import { withDevice } from 'helpers/deviceAccess'
import debugAppInfosForCurrency from 'helpers/debugAppInfosForCurrency'
type Input = {
currencyId: string,
devicePath: string,
}
type Result = {
version?: string,
}
const cmd: Command<Input, Result> = createCommand(
'debugAppInfosForCurrency',
({ currencyId, devicePath }) =>
fromPromise(
withDevice(devicePath)(transport =>
debugAppInfosForCurrency(transport, getCryptoCurrencyById(currencyId)),
),
),
)
export default cmd

2
src/commands/index.js

@ -3,6 +3,7 @@
import invariant from 'invariant' import invariant from 'invariant'
import type { Command } from 'helpers/ipc' import type { Command } from 'helpers/ipc'
import debugAppInfosForCurrency from 'commands/debugAppInfosForCurrency'
import getAddress from 'commands/getAddress' import getAddress from 'commands/getAddress'
import getDeviceInfo from 'commands/getDeviceInfo' import getDeviceInfo from 'commands/getDeviceInfo'
import getCurrentFirmware from 'commands/getCurrentFirmware' import getCurrentFirmware from 'commands/getCurrentFirmware'
@ -34,6 +35,7 @@ import testInterval from 'commands/testInterval'
import uninstallApp from 'commands/uninstallApp' import uninstallApp from 'commands/uninstallApp'
const all: Array<Command<any, any>> = [ const all: Array<Command<any, any>> = [
debugAppInfosForCurrency,
getAddress, getAddress,
getDeviceInfo, getDeviceInfo,
getCurrentFirmware, getCurrentFirmware,

51
src/components/DebugAppInfosForCurrency.js

@ -0,0 +1,51 @@
// @flow
import { Component } from 'react'
import { connect } from 'react-redux'
import { createStructuredSelector } from 'reselect'
import { getCurrentDevice } from 'reducers/devices'
import debugAppInfosForCurrency from 'commands/debugAppInfosForCurrency'
class DebugAppInfosForCurrency extends Component<
{
children?: (?string) => React$Node,
currencyId: string,
device: *,
},
{
version: ?string,
},
> {
state = {
version: null,
}
componentDidMount() {
const { device, currencyId } = this.props
if (device) {
debugAppInfosForCurrency
.send({ currencyId, devicePath: device.path })
.toPromise()
.then(
({ version }) => {
if (this.unmounted) return
this.setState({ version })
},
() => {},
)
}
}
componentWillUnmount() {
this.unmounted = true
}
unmounted = false
render() {
const { children } = this.props
const { version } = this.state
return children ? children(version) : null
}
}
export default connect(
createStructuredSelector({
device: getCurrentDevice,
}),
)(DebugAppInfosForCurrency)

4
src/components/modals/AddAccounts/steps/03-step-import.js

@ -22,6 +22,7 @@ import IconExclamationCircleThin from 'icons/ExclamationCircleThin'
import TranslatedError from 'components/TranslatedError' import TranslatedError from 'components/TranslatedError'
import Spinner from 'components/base/Spinner' import Spinner from 'components/base/Spinner'
import Text from 'components/base/Text' import Text from 'components/base/Text'
import DebugAppInfosForCurrency from 'components/DebugAppInfosForCurrency'
import type { StepProps } from '../index' import type { StepProps } from '../index'
@ -184,13 +185,14 @@ class StepImport extends PureComponent<StepProps> {
} }
renderError() { renderError() {
const { err } = this.props const { err, currency } = this.props
invariant(err, 'Trying to render inexisting error') invariant(err, 'Trying to render inexisting error')
return ( return (
<Box style={{ height: 200 }} px={5} justify="center"> <Box style={{ height: 200 }} px={5} justify="center">
<Box color="alertRed" align="center"> <Box color="alertRed" align="center">
<IconExclamationCircleThin size={43} /> <IconExclamationCircleThin size={43} />
</Box> </Box>
{currency ? <DebugAppInfosForCurrency currencyId={currency.id} /> : null}
<Title> <Title>
<TranslatedError error={err} field="title" /> <TranslatedError error={err} field="title" />
</Title> </Title>

2
src/components/modals/Receive/steps/03-step-confirm-address.js

@ -12,6 +12,7 @@ import ExternalLinkButton from 'components/base/ExternalLinkButton'
import RetryButton from 'components/base/RetryButton' import RetryButton from 'components/base/RetryButton'
import type { StepProps } from '../index' import type { StepProps } from '../index'
import TranslatedError from '../../../TranslatedError' import TranslatedError from '../../../TranslatedError'
import DebugAppInfosForCurrency from '../../../DebugAppInfosForCurrency'
export default class StepConfirmAddress extends PureComponent<StepProps> { export default class StepConfirmAddress extends PureComponent<StepProps> {
render() { render() {
@ -21,6 +22,7 @@ export default class StepConfirmAddress extends PureComponent<StepProps> {
<TrackPage category="Receive Flow" name="Step 3" /> <TrackPage category="Receive Flow" name="Step 3" />
{isAddressVerified === false ? ( {isAddressVerified === false ? (
<Fragment> <Fragment>
{account ? <DebugAppInfosForCurrency currencyId={account.currency.id} /> : null}
<TrackPage category="Receive Flow" name="Step 3 Address Not Verified Error" /> <TrackPage category="Receive Flow" name="Step 3 Address Not Verified Error" />
<Title> <Title>
<TranslatedError error={verifyAddressError} /> <TranslatedError error={verifyAddressError} />

4
src/components/modals/Send/steps/04-step-confirmation.js

@ -13,6 +13,7 @@ import Button from 'components/base/Button'
import Spinner from 'components/base/Spinner' import Spinner from 'components/base/Spinner'
import RetryButton from 'components/base/RetryButton' import RetryButton from 'components/base/RetryButton'
import TranslatedError from 'components/TranslatedError' import TranslatedError from 'components/TranslatedError'
import DebugAppInfosForCurrency from 'components/DebugAppInfosForCurrency'
import IconCheckCircle from 'icons/CheckCircle' import IconCheckCircle from 'icons/CheckCircle'
import IconExclamationCircleThin from 'icons/ExclamationCircleThin' import IconExclamationCircleThin from 'icons/ExclamationCircleThin'
@ -43,7 +44,7 @@ const Text = styled(Box).attrs({
text-align: center; text-align: center;
` `
export default function StepConfirmation({ t, optimisticOperation, error }: StepProps<*>) { export default function StepConfirmation({ account, t, optimisticOperation, error }: StepProps<*>) {
const Icon = optimisticOperation ? IconCheckCircle : error ? IconExclamationCircleThin : Spinner const Icon = optimisticOperation ? IconCheckCircle : error ? IconExclamationCircleThin : Spinner
const iconColor = optimisticOperation const iconColor = optimisticOperation
? colors.positiveGreen ? colors.positiveGreen
@ -53,6 +54,7 @@ export default function StepConfirmation({ t, optimisticOperation, error }: Step
return ( return (
<Container> <Container>
{error && account ? <DebugAppInfosForCurrency currencyId={account.currency.id} /> : null}
<TrackPage category="Send Flow" name="Step 4" /> <TrackPage category="Send Flow" name="Step 4" />
<span style={{ color: iconColor }}> <span style={{ color: iconColor }}>
<Icon size={43} /> <Icon size={43} />

12
src/helpers/debugAppInfosForCurrency/btc.js

@ -0,0 +1,12 @@
// @flow
import type Transport from '@ledgerhq/hw-transport'
import { createCustomErrorClass } from '../errors'
export const BtcUnmatchedApp = createCustomErrorClass('BtcUnmatchedApp')
export default async (transport: Transport<*>) => {
const r = await transport.send(0xe0, 0xc4, 0, 0)
const version = `${r[2]}.${r[3]}.${r[4]}`
return { version }
}

10
src/helpers/debugAppInfosForCurrency/ethereum.js

@ -0,0 +1,10 @@
// @flow
import Eth from '@ledgerhq/hw-app-eth'
import type Transport from '@ledgerhq/hw-transport'
export default async (transport: Transport<*>) => {
const eth = new Eth(transport)
const { version } = await eth.getAppConfiguration()
return { version }
}

29
src/helpers/debugAppInfosForCurrency/index.js

@ -0,0 +1,29 @@
// @flow
import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types'
import invariant from 'invariant'
import type Transport from '@ledgerhq/hw-transport'
import bitcoin from './btc'
import ethereum from './ethereum'
import ripple from './ripple'
type Resolver = (
transport: Transport<*>,
currency: CryptoCurrency,
) => Promise<{
version?: string,
}>
const perFamily: { [_: string]: * } = {
bitcoin,
ethereum,
ripple,
}
const proxy: Resolver = (transport, currency) => {
const getAddress = perFamily[currency.family]
invariant(getAddress, `getAddress not implemented for ${currency.id}`)
return getAddress(transport)
}
export default proxy

10
src/helpers/debugAppInfosForCurrency/ripple.js

@ -0,0 +1,10 @@
// @flow
import Xrp from '@ledgerhq/hw-app-xrp'
import type Transport from '@ledgerhq/hw-transport'
export default async (transport: Transport<*>) => {
const xrp = new Xrp(transport)
const { version } = await xrp.getAppConfiguration()
return { version }
}
Loading…
Cancel
Save