Browse Source

Merge branch 'master' of github.com:ledgerhq/ledger-live-desktop into pixel-push

master
Gaëtan Renaudeau 7 years ago
parent
commit
781c113e13
  1. 11
      src/commands/listApps.js
  2. 2
      src/components/AccountPage/index.js
  3. 1
      src/components/DashboardPage/index.js
  4. 19
      src/components/MainSideBar.js
  5. 6
      src/components/ManagerPage/AppsList.js
  6. 24
      src/components/OperationsList/index.js
  7. 6
      src/components/OperationsList/stories.js
  8. 30
      src/components/PillsDaysCount.js
  9. 31
      src/components/modals/AccountSettingRenderBody.js
  10. 4
      src/components/modals/ImportAccounts/AccountRow.js
  11. 12
      src/components/modals/ImportAccounts/steps/01-step-choose-currency.js
  12. 209
      src/components/modals/ImportAccounts/steps/03-step-import.js
  13. 16
      src/helpers/apps/listApps.js
  14. 1
      src/helpers/constants.js
  15. 3
      src/helpers/derivations.js
  16. 2
      src/helpers/devices/getFirmwareInfo.js
  17. 3
      src/helpers/devices/getLatestFirmwareForDevice.js
  18. 1
      src/renderer/i18n/instanciate.js
  19. 12
      static/i18n/en/importAccounts.yml
  20. 4
      static/i18n/en/settings.yml

11
src/commands/listApps.js

@ -5,15 +5,14 @@ import { fromPromise } from 'rxjs/observable/fromPromise'
import listApps from 'helpers/apps/listApps' import listApps from 'helpers/apps/listApps'
// type Input = { type Input = {
// targetId: string | number, targetId: string | number,
// } }
type Input = *
type Result = * type Result = *
const cmd: Command<Input, Result> = createCommand('listApps', () => const cmd: Command<Input, Result> = createCommand('listApps', ({ targetId }) =>
/* { targetId } */ fromPromise(listApps(/* targetId */)), fromPromise(listApps(targetId)),
) )
export default cmd export default cmd

2
src/components/AccountPage/index.js

@ -180,7 +180,7 @@ class AccountPage extends PureComponent<Props, State> {
)} )}
/> />
</Box> </Box>
<OperationsList canShowMore account={account} title={t('account:lastOperations')} /> <OperationsList account={account} title={t('account:lastOperations')} />
</Fragment> </Fragment>
) : ( ) : (
<EmptyStateAccount account={account} /> <EmptyStateAccount account={account} />

1
src/components/DashboardPage/index.js

@ -168,7 +168,6 @@ class DashboardPage extends PureComponent<Props, State> {
</Box> </Box>
{displayOperations && ( {displayOperations && (
<OperationsList <OperationsList
canShowMore
onAccountClick={this.onAccountClick} onAccountClick={this.onAccountClick}
accounts={accounts} accounts={accounts}
title={t('dashboard:recentActivity')} title={t('dashboard:recentActivity')}

19
src/components/MainSideBar.js

@ -17,10 +17,13 @@ import type { UpdateStatus } from 'reducers/update'
import { MODAL_RECEIVE, MODAL_SEND } from 'config/constants' import { MODAL_RECEIVE, MODAL_SEND } from 'config/constants'
import { rgba } from 'styles/helpers'
import { accountsSelector } from 'reducers/accounts' import { accountsSelector } from 'reducers/accounts'
import { openModal } from 'reducers/modals' import { openModal } from 'reducers/modals'
import { getUpdateStatus } from 'reducers/update' import { getUpdateStatus } from 'reducers/update'
import Tooltip from 'components/base/Tooltip'
import { SideBarList } from 'components/base/SideBar' import { SideBarList } from 'components/base/SideBar'
import Box, { Tabbable } from 'components/base/Box' import Box, { Tabbable } from 'components/base/Box'
import Space from 'components/base/Space' import Space from 'components/base/Space'
@ -140,9 +143,11 @@ class MainSideBar extends PureComponent<Props> {
scroll scroll
title={t('sidebar:accounts')} title={t('sidebar:accounts')}
titleRight={ titleRight={
<PlusWrapper onClick={() => openModal('importAccounts')}> <Tooltip render={() => t('importAccounts:title')}>
<IconCirclePlus size={16} /> <PlusWrapper onClick={() => openModal('importAccounts')}>
</PlusWrapper> <IconCirclePlus size={16} />
</PlusWrapper>
</Tooltip>
} }
items={accountsItems} items={accountsItems}
emptyText={t('emptyState:sidebar.text')} emptyText={t('emptyState:sidebar.text')}
@ -157,15 +162,15 @@ const PlusWrapper = styled(Tabbable).attrs({
cursor: 'pointer', cursor: 'pointer',
borderRadius: 1, borderRadius: 1,
})` })`
opacity: 0.4; color: ${p => p.theme.colors.smoke};
&:hover { &:hover {
opacity: 1; color: ${p => p.theme.colors.dark};
} }
border: 1px dashed rgba(0, 0, 0, 0); border: 1px solid transparent;
&:focus { &:focus {
border: 1px dashed rgba(0, 0, 0, 0.2);
outline: none; outline: none;
border-color: ${p => rgba(p.theme.colors.wallet, 0.3)};
} }
` `

6
src/components/ManagerPage/AppsList.js

@ -46,7 +46,7 @@ type LedgerApp = {
type Props = { type Props = {
device: Device, device: Device,
// targetId: string | number, targetId: string | number,
t: T, t: T,
} }
@ -75,8 +75,8 @@ class AppsList extends PureComponent<Props, State> {
async fetchAppList() { async fetchAppList() {
try { try {
// const { targetId } = this.props // TODO: REUSE THIS WHEN SERVER IS UP const { targetId } = this.props
const appsList = CACHED_APPS || (await listApps.send().toPromise()) const appsList = CACHED_APPS || (await listApps.send({ targetId }).toPromise())
CACHED_APPS = appsList CACHED_APPS = appsList
if (!this._unmounted) { if (!this._unmounted) {
this.setState({ appsList, status: 'idle' }) this.setState({ appsList, status: 'idle' })

24
src/components/OperationsList/index.js

@ -52,8 +52,7 @@ const mapDispatchToProps = {
type Props = { type Props = {
account: Account, account: Account,
accounts: Account[], accounts: Account[],
canShowMore: boolean, openModal: (string, Object) => *,
openModal: Function,
t: T, t: T,
withAccount?: boolean, withAccount?: boolean,
title?: string, title?: string,
@ -66,10 +65,12 @@ type State = {
const initialState = { const initialState = {
nbToShow: 20, nbToShow: 20,
} }
const footerPlaceholder = null // TODO figure out with design what we want here
export class OperationsList extends PureComponent<Props, State> { export class OperationsList extends PureComponent<Props, State> {
static defaultProps = { static defaultProps = {
withAccount: false, withAccount: false,
canShowMore: false,
} }
state = initialState state = initialState
@ -86,7 +87,7 @@ export class OperationsList extends PureComponent<Props, State> {
} }
render() { render() {
const { account, accounts, canShowMore, t, title, withAccount } = this.props const { account, accounts, t, title, withAccount } = this.props
const { nbToShow } = this.state const { nbToShow } = this.state
if (!account && !accounts) { if (!account && !accounts) {
@ -130,13 +131,14 @@ export class OperationsList extends PureComponent<Props, State> {
</Card> </Card>
</Box> </Box>
))} ))}
{canShowMore && {!groupedOperations.completed ? (
!groupedOperations.completed && ( <ShowMore onClick={this.fetchMoreOperations}>
<ShowMore onClick={this.fetchMoreOperations}> <span>{t('operationsList:showMore')}</span>
<span>{t('operationsList:showMore')}</span> <IconAngleDown size={12} />
<IconAngleDown size={12} /> </ShowMore>
</ShowMore> ) : (
)} footerPlaceholder
)}
</Box> </Box>
</Defer> </Defer>
) )

6
src/components/OperationsList/stories.js

@ -15,10 +15,6 @@ const account2 = genAccount('account2')
stories.add('OperationsList', () => ( stories.add('OperationsList', () => (
<Box bg="lightGrey" p={6} m={-4}> <Box bg="lightGrey" p={6} m={-4}>
<OperationsList <OperationsList accounts={[account1, account2]} withAccount={boolean('withAccount')} />
accounts={[account1, account2]}
canShowMore={boolean('canShowMore')}
withAccount={boolean('withAccount')}
/>
</Box> </Box>
)) ))

30
src/components/PillsDaysCount.js

@ -1,6 +1,6 @@
// @flow // @flow
import React from 'react' import React, { PureComponent } from 'react'
import { translate } from 'react-i18next' import { translate } from 'react-i18next'
import type { T } from 'types/common' import type { T } from 'types/common'
@ -9,7 +9,7 @@ import Pills from 'components/base/Pills'
type Props = { type Props = {
selectedTime: string, selectedTime: string,
onChange: Function, onChange: ({ key: string, value: *, label: string }) => void,
t: T, t: T,
} }
@ -19,18 +19,20 @@ const itemsTimes = [
{ key: 'year', value: 365 }, { key: 'year', value: 365 },
] ]
function PillsDaysCount(props: Props) { class PillsDaysCount extends PureComponent<Props> {
const { selectedTime, onChange, t } = props render() {
return ( const { selectedTime, onChange, t } = this.props
<Pills return (
items={itemsTimes.map(item => ({ <Pills
...item, items={itemsTimes.map(item => ({
label: t(`time:${item.key}`), ...item,
}))} label: t(`time:${item.key}`),
activeKey={selectedTime} }))}
onChange={onChange} activeKey={selectedTime}
/> onChange={onChange}
) />
)
}
} }
export default translate()(PillsDaysCount) export default translate()(PillsDaysCount)

31
src/components/modals/AccountSettingRenderBody.js

@ -20,12 +20,19 @@ import Box from 'components/base/Box'
import Button from 'components/base/Button' import Button from 'components/base/Button'
import Input from 'components/base/Input' import Input from 'components/base/Input'
import Select from 'components/base/LegacySelect' import Select from 'components/base/LegacySelect'
import { ModalBody, ModalTitle, ModalFooter, ModalContent } from 'components/base/Modal' import {
ModalBody,
ModalTitle,
ModalFooter,
ModalContent,
ConfirmModal,
} from 'components/base/Modal'
type State = { type State = {
accountName: string | null, accountName: string | null,
accountUnit: Unit | null, accountUnit: Unit | null,
accountNameError: boolean, accountNameError: boolean,
isRemoveAccountModalOpen: boolean,
} }
type Props = { type Props = {
@ -47,6 +54,7 @@ const defaultState = {
accountName: null, accountName: null,
accountUnit: null, accountUnit: null,
accountNameError: false, accountNameError: false,
isRemoveAccountModalOpen: false,
} }
class HelperComp extends PureComponent<Props, State> { class HelperComp extends PureComponent<Props, State> {
@ -106,15 +114,18 @@ class HelperComp extends PureComponent<Props, State> {
handleChangeUnit = (value: Unit) => { handleChangeUnit = (value: Unit) => {
this.setState({ accountUnit: value }) this.setState({ accountUnit: value })
} }
handleOpenRemoveAccountModal = () => this.setState({ isRemoveAccountModalOpen: true })
handleCloseRemoveAccountModal = () => this.setState({ isRemoveAccountModalOpen: false })
handleRemoveAccount = (account: Account) => { handleRemoveAccount = (account: Account) => {
const { removeAccount } = this.props const { removeAccount, onClose } = this.props
removeAccount(account) removeAccount(account)
this.props.onClose() this.setState({ isRemoveAccountModalOpen: false })
onClose()
} }
render() { render() {
const { accountUnit, accountNameError } = this.state const { accountUnit, accountNameError, isRemoveAccountModalOpen } = this.state
const { t, onClose, data } = this.props const { t, onClose, data } = this.props
const account = this.getAccount(data) const account = this.getAccount(data)
@ -183,7 +194,7 @@ class HelperComp extends PureComponent<Props, State> {
</Spoiler> </Spoiler>
</ModalContent> </ModalContent>
<ModalFooter horizontal> <ModalFooter horizontal>
<Button small danger type="button" onClick={() => this.handleRemoveAccount(account)}> <Button small danger type="button" onClick={this.handleOpenRemoveAccountModal}>
{t('common:delete')} {t('common:delete')}
</Button> </Button>
<Button small ml="auto" type="submit" primary> <Button small ml="auto" type="submit" primary>
@ -191,6 +202,16 @@ class HelperComp extends PureComponent<Props, State> {
</Button> </Button>
</ModalFooter> </ModalFooter>
</form> </form>
<ConfirmModal
isDanger
isOpened={isRemoveAccountModalOpen}
onClose={this.handleCloseRemoveAccountModal}
onReject={this.handleCloseRemoveAccountModal}
onConfirm={() => this.handleRemoveAccount(account)}
title={t('settings:removeAccountModal.title')}
subTitle={t('settings:removeAccountModal.subTitle')}
desc={t('settings:removeAccountModal.desc')}
/>
</ModalBody> </ModalBody>
) )
} }

4
src/components/modals/ImportAccounts/AccountRow.js

@ -17,7 +17,7 @@ import IconCheck from 'icons/Check'
type Props = { type Props = {
account: Account, account: Account,
isChecked: boolean, isChecked: boolean,
isDisabled: boolean, isDisabled?: boolean,
onClick: Account => void, onClick: Account => void,
onAccountUpdate: Account => void, onAccountUpdate: Account => void,
} }
@ -110,7 +110,7 @@ export default class AccountRow extends PureComponent<Props, State> {
fontSize={4} fontSize={4}
color="grey" color="grey"
/> />
<Radio isChecked={isChecked || isDisabled} /> <Radio isChecked={isChecked || !!isDisabled} />
</AccountRowContainer> </AccountRowContainer>
) )
} }

12
src/components/modals/ImportAccounts/steps/01-step-choose-currency.js

@ -1,6 +1,7 @@
// @flow // @flow
import React, { Fragment } from 'react' import React, { Fragment } from 'react'
import isArray from 'lodash/isArray'
import SelectCurrency from 'components/SelectCurrency' import SelectCurrency from 'components/SelectCurrency'
import Button from 'components/base/Button' import Button from 'components/base/Button'
@ -9,7 +10,16 @@ import CurrencyBadge from 'components/base/CurrencyBadge'
import type { StepProps } from '../index' import type { StepProps } from '../index'
function StepChooseCurrency({ currency, setState }: StepProps) { function StepChooseCurrency({ currency, setState }: StepProps) {
return <SelectCurrency onChange={currency => setState({ currency })} value={currency} /> return (
<SelectCurrency
onChange={currency => {
setState({
currency: isArray(currency) && currency.length === 0 ? null : currency,
})
}}
value={currency}
/>
)
} }
export function StepChooseCurrencyFooter({ transitionTo, currency, t }: StepProps) { export function StepChooseCurrencyFooter({ transitionTo, currency, t }: StepProps) {

209
src/components/modals/ImportAccounts/steps/03-step-import.js

@ -1,7 +1,9 @@
// @flow // @flow
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import styled from 'styled-components'
import type { Account } from '@ledgerhq/live-common/lib/types' import type { Account } from '@ledgerhq/live-common/lib/types'
import uniq from 'lodash/uniq'
import { getBridgeForCurrency } from 'bridge' import { getBridgeForCurrency } from 'bridge'
@ -48,10 +50,18 @@ class StepImport extends PureComponent<StepProps> {
this.scanSubscription = bridge.scanAccountsOnDevice(currency, devicePath, { this.scanSubscription = bridge.scanAccountsOnDevice(currency, devicePath, {
next: account => { next: account => {
const { scannedAccounts } = this.props const { scannedAccounts, checkedAccountsIds, existingAccounts } = this.props
const hasAlreadyBeenScanned = !!scannedAccounts.find(a => account.id === a.id) const hasAlreadyBeenScanned = !!scannedAccounts.find(a => account.id === a.id)
const hasAlreadyBeenImported = !!existingAccounts.find(a => account.id === a.id)
const isNewAccount = account.operations.length === 0
if (!hasAlreadyBeenScanned) { if (!hasAlreadyBeenScanned) {
setState({ scannedAccounts: [...scannedAccounts, account] }) setState({
scannedAccounts: [...scannedAccounts, account],
checkedAccountsIds:
!hasAlreadyBeenImported && !isNewAccount
? uniq([...checkedAccountsIds, account.id])
: checkedAccountsIds,
})
} }
}, },
complete: () => setState({ scanStatus: 'finished' }), complete: () => setState({ scanStatus: 'finished' }),
@ -103,63 +113,125 @@ class StepImport extends PureComponent<StepProps> {
}) })
} }
handleToggleSelectAll = () => { handleSelectAll = () => {
const { scannedAccounts, setState } = this.props const { scannedAccounts, setState } = this.props
setState({ checkedAccountsIds: scannedAccounts.map(a => a.id) }) setState({
checkedAccountsIds: scannedAccounts.filter(a => a.operations.length > 0).map(a => a.id),
})
} }
handleUnselectAll = () => this.props.setState({ checkedAccountsIds: [] })
render() { render() {
const { scanStatus, err, scannedAccounts, checkedAccountsIds, existingAccounts } = this.props const { scanStatus, err, scannedAccounts, checkedAccountsIds, existingAccounts, t } = this.props
const importableAccounts = scannedAccounts.filter(acc => {
if (acc.operations.length <= 0) {
return false
}
return existingAccounts.find(a => a.id === acc.id) === undefined
})
const creatableAccounts = scannedAccounts.filter(acc => {
if (acc.operations.length > 0) {
return false
}
return existingAccounts.find(a => a.id === acc.id) === undefined
})
const isAllSelected = scannedAccounts.filter(acc => acc.operations.length > 0).every(acc => {
const isChecked = !!checkedAccountsIds.find(id => acc.id === id)
const isImported = !!existingAccounts.find(a => acc.id === a.id)
return isChecked || isImported
})
return ( return (
<Box> <Box>
{err && <Box shrink>{err.message}</Box>} {err && <Box shrink>{err.message}</Box>}
{!!scannedAccounts.length && ( <Box flow={5}>
<Box horizontal justify="flex-end" mb={2}> {(!!importableAccounts.length || scanStatus === 'scanning') && (
<FakeLink onClick={this.handleToggleSelectAll} fontSize={3}> <Box>
{'Select all'} {!!importableAccounts.length && (
</FakeLink> <Box horizontal mb={3} align="center">
</Box> <Box
)} ff="Open Sans|Bold"
color="dark"
<Box flow={2}> fontSize={2}
{scannedAccounts.map(account => { style={{ textTransform: 'uppercase' }}
const isChecked = checkedAccountsIds.find(id => id === account.id) !== undefined >
const existingAccount = existingAccounts.find(a => a.id === account.id) {t('importAccounts:accountToImportSubtitle', {
const isDisabled = existingAccount !== undefined count: importableAccounts.length,
return ( })}
</Box>
<FakeLink
ml="auto"
onClick={isAllSelected ? this.handleUnselectAll : this.handleSelectAll}
fontSize={3}
>
{isAllSelected
? t('importAccounts:unselectAll')
: t('importAccounts:selectAll')}
</FakeLink>
</Box>
)}
<Box flow={2}>
{importableAccounts.map(account => {
const isChecked = checkedAccountsIds.find(id => id === account.id) !== undefined
const existingAccount = existingAccounts.find(a => a.id === account.id)
const isDisabled = existingAccount !== undefined
return (
<AccountRow
key={account.id}
account={existingAccount || account}
isChecked={isChecked}
isDisabled={isDisabled}
onClick={this.handleToggleAccount}
onAccountUpdate={this.handleAccountUpdate}
/>
)
})}
{scanStatus === 'scanning' && (
<LoadingRow>
<Spinner color="grey" size={16} />
</LoadingRow>
)}
</Box>
</Box>
)}
{creatableAccounts.length > 0 && (
<Box>
<Box horizontal mb={3} align="center">
<Box
ff="Open Sans|Bold"
color="dark"
fontSize={2}
style={{ textTransform: 'uppercase' }}
>
{t('importAccounts:createNewAccount')}
</Box>
</Box>
<AccountRow <AccountRow
key={account.id} account={creatableAccounts[0]}
account={existingAccount || account} isChecked={
isChecked={isChecked} checkedAccountsIds.find(id => id === creatableAccounts[0].id) !== undefined
isDisabled={isDisabled} }
onClick={this.handleToggleAccount} onClick={this.handleToggleAccount}
onAccountUpdate={this.handleAccountUpdate} onAccountUpdate={this.handleAccountUpdate}
/> />
)
})}
{scanStatus === 'scanning' && (
<Box
horizontal
bg="lightGrey"
borderRadius={3}
px={3}
align="center"
justify="center"
style={{ height: 48 }}
>
<Spinner color="grey" size={24} />
</Box> </Box>
)} )}
</Box> </Box>
<Box horizontal mt={2}> <Box horizontal mt={2}>
{['error', 'finished'].includes(scanStatus) && ( {['error'].includes(scanStatus) && (
<Button small outline onClick={this.handleRetry}> <Button small outline onClick={this.handleRetry}>
<Box horizontal flow={2} align="center"> <Box horizontal flow={2} align="center">
<IconExchange size={13} /> <IconExchange size={13} />
<span>{'retry sync'}</span> <span>{t('importAccounts:retrySync')}</span>
</Box> </Box>
</Button> </Button>
)} )}
@ -171,12 +243,55 @@ class StepImport extends PureComponent<StepProps> {
export default StepImport export default StepImport
export const StepImportFooter = ({ scanStatus, onClickImport, checkedAccountsIds }: StepProps) => ( export const LoadingRow = styled(Box).attrs({
<Button horizontal: true,
primary borderRadius: 1,
disabled={scanStatus !== 'finished' || checkedAccountsIds.length === 0} px: 3,
onClick={() => onClickImport()} align: 'center',
> justify: 'center',
{'Import accounts'} })`
</Button> height: 48px;
) border: 1px dashed ${p => p.theme.colors.fog};
`
export const StepImportFooter = ({
scanStatus,
onClickImport,
checkedAccountsIds,
scannedAccounts,
t,
}: StepProps) => {
const willCreateAccount = checkedAccountsIds.some(id => {
const account = scannedAccounts.find(a => a.id === id)
return account && account.operations.length === 0
})
const willImportAccounts = checkedAccountsIds.some(id => {
const account = scannedAccounts.find(a => a.id === id)
return account && account.operations.length > 0
})
const importedAccountsCount = checkedAccountsIds.filter(id => {
const account = scannedAccounts.find(acc => acc.id === id)
return account && account.operations.length > 0
}).length
const ctaWording =
willCreateAccount && willImportAccounts
? `${t('importAccounts:cta.create')} / ${t('importAccounts:cta.import', {
count: importedAccountsCount,
})}`
: willCreateAccount
? t('importAccounts:cta.create')
: t('importAccounts:cta.import', { count: importedAccountsCount })
return (
<Button
primary
disabled={scanStatus !== 'finished' || checkedAccountsIds.length === 0}
onClick={() => onClickImport()}
>
{ctaWording}
</Button>
)
}

16
src/helpers/apps/listApps.js

@ -1,18 +1,18 @@
// @flow // @flow
import axios from 'axios' import axios from 'axios'
// const { API_BASE_URL } = process.env import { API_BASE_URL } from 'helpers/constants'
export default async (/* targetId: string | number */) => { export default async (targetId: string | number) => {
try { try {
// const { data: deviceData } = await axios.get( const { data: deviceData } = await axios.get(
// `${API_BASE_URL}/device_versions_target_id/${targetId}`, `${API_BASE_URL}/device_versions_target_id/${targetId}`,
// ) )
const { data } = await axios.get('https://api.ledgerwallet.com/update/applications') const { data } = await axios.get('https://api.ledgerwallet.com/update/applications')
// if (deviceData.name in data) { if (deviceData.name in data) {
// return data[deviceData.name] return data[deviceData.name]
// } }
return data['nanos-1.4'] return data['nanos-1.4']
} catch (err) { } catch (err) {

1
src/helpers/constants.js

@ -2,6 +2,7 @@
export const BASE_SOCKET_URL = 'ws://api.ledgerwallet.com' export const BASE_SOCKET_URL = 'ws://api.ledgerwallet.com'
export const BASE_SOCKET_URL_TEMP = 'ws://manager.ledger.fr:3500' export const BASE_SOCKET_URL_TEMP = 'ws://manager.ledger.fr:3500'
export const API_BASE_URL = process.env.API_BASE_URL || 'https://beta.manager.live.ledger.fr/api'
// If you want to test locally with https://github.com/LedgerHQ/ledger-update-python-api // If you want to test locally with https://github.com/LedgerHQ/ledger-update-python-api
// export const BASE_SOCKET_URL = 'ws://localhost:3001/update' // export const BASE_SOCKET_URL = 'ws://localhost:3001/update'

3
src/helpers/derivations.js

@ -11,9 +11,12 @@ const ethLegacyMEW: Derivation = ({ x }) => `44'/60'/0'/${x}`
const etcLegacyMEW: Derivation = ({ x }) => `44'/60'/160720'/${x}` const etcLegacyMEW: Derivation = ({ x }) => `44'/60'/160720'/${x}`
const rippleLegacy: Derivation = ({ x }) => `44'/144'/0'/${x}'`
const legacyDerivations = { const legacyDerivations = {
ethereum: [ethLegacyMEW], ethereum: [ethLegacyMEW],
ethereum_classic: [etcLegacyMEW], ethereum_classic: [etcLegacyMEW],
ripple: [rippleLegacy],
} }
export const standardDerivation: Derivation = ({ currency, segwit, x }) => { export const standardDerivation: Derivation = ({ currency, segwit, x }) => {

2
src/helpers/devices/getFirmwareInfo.js

@ -2,7 +2,7 @@
import axios from 'axios' import axios from 'axios'
import isEmpty from 'lodash/isEmpty' import isEmpty from 'lodash/isEmpty'
const { API_BASE_URL } = process.env import { API_BASE_URL } from 'helpers/constants'
type Input = { type Input = {
version: string, version: string,

3
src/helpers/devices/getLatestFirmwareForDevice.js

@ -1,11 +1,10 @@
// @flow // @flow
import axios from 'axios' import axios from 'axios'
import isEmpty from 'lodash/isEmpty' import isEmpty from 'lodash/isEmpty'
import { API_BASE_URL } from 'helpers/constants'
import getFirmwareInfo from './getFirmwareInfo' import getFirmwareInfo from './getFirmwareInfo'
const { API_BASE_URL } = process.env
type Input = { type Input = {
targetId: string | number, targetId: string | number,
version: string, version: string,

1
src/renderer/i18n/instanciate.js

@ -3,6 +3,7 @@ import i18n from 'i18next'
const commonConfig = { const commonConfig = {
fallbackLng: 'en', fallbackLng: 'en',
debug: false, debug: false,
compatibilityJSON: 'v2',
react: { react: {
wait: process.env.NODE_ENV !== 'test', wait: process.env.NODE_ENV !== 'test',
}, },

12
static/i18n/en/importAccounts.yml

@ -1,6 +1,16 @@
title: Import accounts title: Add accounts
breadcrumb: breadcrumb:
informations: Informations informations: Informations
connectDevice: Connect device connectDevice: Connect device
import: Import import: Import
finish: End finish: End
accountToImportSubtitle: Account to import
accountToImportSubtitle_plural: 'Accounts to import ({{count}})'
selectAll: Select all
unselectAll: Unselect all
createNewAccount: Create new account
retrySync: Retry sync
cta:
create: 'Create account'
import: 'Import account'
import_plural: 'Import accounts'

4
static/i18n/en/settings.yml

@ -57,6 +57,10 @@ softResetModal:
title: Clean application cache title: Clean application cache
subTitle: Are you sure houston? subTitle: Are you sure houston?
desc: Lorem ipsum dolor sit amet desc: Lorem ipsum dolor sit amet
removeAccountModal:
title: Delete this account
subTitle: Are you sure houston?
desc: Lorem ipsum dolor sit amet
exportLogs: exportLogs:
title: Export Logs title: Export Logs
desc: Export Logs desc: Export Logs

Loading…
Cancel
Save