diff --git a/.circleci/config.yml b/.circleci/config.yml index 44b9ab2b..75ad028a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,12 +15,6 @@ jobs: - run: name: Dependencies command: yarn - - run: - name: Flow typed - command: yarn flow-typed - - run: - name: Temporary remove broken flow definitions - command: rm flow-typed/npm/{react-i18next_v7.x.x.js,react-redux_v5.x.x.js,styled-components_v3.x.x.js} - run: name: Lint command: yarn lint diff --git a/.eslintrc b/.eslintrc index 65914441..a3ed346b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -51,6 +51,7 @@ "react/jsx-filename-extension": 0, "react/jsx-no-target-blank": 0, "react/prefer-stateless-function": 0, + "react/require-default-props": 0, }, "settings": { "import/resolver": { diff --git a/README.md b/README.md index 80f1ec30..58ab95cf 100644 --- a/README.md +++ b/README.md @@ -13,17 +13,13 @@ Project has been tested under [NodeJS](https://nodejs.org) v9.3.0, with [Yarn](h #### Setup -1. Install dependencies +1. Install dependencies ```bash -# app dependencies yarn - -# npm packages flow definitions -yarn flow-typed ``` -2. Create `.env` file +2. Create `.env` file ```bash # ENV VARIABLES diff --git a/package.json b/package.json index 11a990f7..68711621 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,8 @@ "dist": "yarn compile && electron-builder", "test": "jest", "flow": "flow", - "flow-typed": "flow-typed install -s --overwrite", "lint": "eslint src webpack .storybook", "postinstall": "bash ./scripts/postinstall.sh", - "precommit": "lint-staged", "prettier": "prettier --write \"{src,webpack,.storybook}/**/*.js\"", "publish-storybook": "bash ./scripts/publish-storybook.sh", "release": "build", @@ -23,13 +21,6 @@ "storybook": "NODE_ENV=development STORYBOOK_ENV=1 start-storybook -s ./static -p 4444", "trans": "node scripts/trans" }, - "lint-staged": { - "*.js": [ - "eslint --fix", - "prettier --write", - "git add" - ] - }, "electronWebpack": { "title": true, "renderer": { @@ -44,12 +35,11 @@ "webpack-sources": "1.0.1" }, "dependencies": { - "@ledgerhq/currencies": "^4.10.1", "@ledgerhq/hw-app-btc": "^4.7.3", "@ledgerhq/hw-app-eth": "^4.7.3", "@ledgerhq/hw-transport": "^4.7.3", "@ledgerhq/hw-transport-node-hid": "^4.7.6", - "@ledgerhq/wallet-common": "^1.2.0", + "@ledgerhq/live-common": "^2.0.0-rc4", "axios": "^0.18.0", "babel-runtime": "^6.26.0", "bcryptjs": "^2.4.3", @@ -89,6 +79,7 @@ "redux": "^4.0.0", "redux-actions": "^2.3.0", "redux-thunk": "^2.2.0", + "reselect": "^3.0.1", "smooth-scrollbar": "^8.2.7", "source-map": "0.7.2", "source-map-support": "^0.5.4", @@ -140,7 +131,6 @@ "husky": "^0.14.3", "jest": "^22.4.3", "js-yaml": "^3.10.0", - "lint-staged": "^7.0.4", "node-loader": "^0.6.0", "prettier": "^1.12.1", "react-hot-loader": "^4.1.0", diff --git a/scripts/postinstall.sh b/scripts/postinstall.sh index 9777a2b6..5ef5a1d4 100755 --- a/scripts/postinstall.sh +++ b/scripts/postinstall.sh @@ -1,3 +1,5 @@ #/bin/bash +flow-typed install -s --overwrite +rm flow-typed/npm/{react-i18next_v7.x.x.js,react-redux_v5.x.x.js,styled-components_v3.x.x.js} electron-builder install-app-deps diff --git a/src/actions/accounts.js b/src/actions/accounts.js index 679f7aac..666df151 100644 --- a/src/actions/accounts.js +++ b/src/actions/accounts.js @@ -1,7 +1,7 @@ // @flow import sortBy from 'lodash/sortBy' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import db from 'helpers/db' diff --git a/src/actions/counterValues.js b/src/actions/counterValues.js index 0f67e94e..a7ee2eca 100644 --- a/src/actions/counterValues.js +++ b/src/actions/counterValues.js @@ -1,12 +1,13 @@ // @flow -import { getFiatUnit } from '@ledgerhq/currencies' -import { fetchHistodayRates } from '@ledgerhq/wallet-common/lib/api/countervalue' - -import type { Currency } from '@ledgerhq/currencies' import type { Dispatch } from 'redux' +import { fetchHistodayRates } from '@ledgerhq/live-common/lib/api/countervalue' +import type { CryptoCurrency, Currency } from '@ledgerhq/live-common/lib/types' +import { counterValueCurrencySelector } from 'reducers/settings' +import { currenciesSelector } from 'reducers/accounts' import db from 'helpers/db' +import type { State } from 'reducers' export type InitCounterValues = () => { type: string, payload: Object } export const initCounterValues: InitCounterValues = () => ({ @@ -20,18 +21,23 @@ export const updateCounterValues: UpdateCounterValues = payload => ({ payload, }) -export type FetchCounterValues = (?(Currency[])) => (Dispatch<*>, Function) => Promise -export const fetchCounterValues: FetchCounterValues = (currencies: ?(Currency[])) => async ( - dispatch, - getState, -) => { - const { accounts, settings } = getState() +function cryptoCurrenciesToCurrencies(currencies: CryptoCurrency[]): Currency[] { + // $FlowFixMe this function is just to fix flow types. array contravariant issue. + return currencies +} + +export type FetchCounterValues = ( + currencies?: Currency[], +) => (Dispatch<*>, () => State) => Promise + +export const fetchCounterValues: FetchCounterValues = currencies => async (dispatch, getState) => { + const state = getState() + const currency = counterValueCurrencySelector(state) + if (!currency) return if (!currencies) { - currencies = accounts.map(a => a.currency) + // TODO this should be default, there is no need to provide the currencies in parameter + currencies = cryptoCurrenciesToCurrencies(currenciesSelector(state)) } - - const { counterValue } = settings - const fiatUnit = getFiatUnit(counterValue) - const counterValues = await fetchHistodayRates(currencies, fiatUnit) + const counterValues = await fetchHistodayRates(currencies, currency) dispatch(updateCounterValues(counterValues)) } diff --git a/src/components/AccountPage/AccountHeader.js b/src/components/AccountPage/AccountHeader.js index e9b34b57..5c038fc3 100644 --- a/src/components/AccountPage/AccountHeader.js +++ b/src/components/AccountPage/AccountHeader.js @@ -1,13 +1,13 @@ // @flow import React, { PureComponent } from 'react' -import { getIconByCoinType } from '@ledgerhq/currencies/react' import styled from 'styled-components' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import Box from 'components/base/Box' import Text from 'components/base/Text' +import CryptoCurrencyIcon from '../CryptoCurrencyIcon' const CurName = styled(Text).attrs({ ff: 'Open Sans|SemiBold', @@ -32,14 +32,11 @@ type Props = { class AccountHeader extends PureComponent { render() { const { account } = this.props - const Icon = getIconByCoinType(account.currency.coinType) return ( - {Icon && ( - - - - )} + + + {account.currency.name} {account.name} diff --git a/src/components/AccountPage/index.js b/src/components/AccountPage/index.js index 2ed8ab2a..64d96128 100644 --- a/src/components/AccountPage/index.js +++ b/src/components/AccountPage/index.js @@ -7,9 +7,12 @@ import { connect } from 'react-redux' import { translate } from 'react-i18next' import { Redirect } from 'react-router' import styled from 'styled-components' -import { formatCurrencyUnit, getFiatUnit } from '@ledgerhq/currencies' +import { + formatCurrencyUnit, + getFiatCurrencyByTicker, +} from '@ledgerhq/live-common/lib/helpers/currencies' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import { MODAL_SEND, MODAL_RECEIVE, MODAL_SETTINGS_ACCOUNT } from 'config/constants' @@ -95,9 +98,13 @@ class AccountPage extends PureComponent { currency: formatCurrencyUnit(account.unit, account.balance, { showCode: true, }), - counterValue: formatCurrencyUnit(getFiatUnit(counterValue), data.totalBalance, { - showCode: true, - }), + counterValue: formatCurrencyUnit( + getFiatCurrencyByTicker(counterValue).units[0], + data.totalBalance, + { + showCode: true, + }, + ), }, }) } diff --git a/src/components/BalanceSummary/BalanceInfos.js b/src/components/BalanceSummary/BalanceInfos.js index 3e5908d6..2e8768d2 100644 --- a/src/components/BalanceSummary/BalanceInfos.js +++ b/src/components/BalanceSummary/BalanceInfos.js @@ -3,7 +3,7 @@ import React from 'react' import styled from 'styled-components' -import type { Unit } from '@ledgerhq/currencies' +import type { Unit } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' import Box from 'components/base/Box' diff --git a/src/components/BalanceSummary/index.js b/src/components/BalanceSummary/index.js index 2e88f892..62022750 100644 --- a/src/components/BalanceSummary/index.js +++ b/src/components/BalanceSummary/index.js @@ -1,8 +1,8 @@ // @flow import React, { Fragment } from 'react' -import type { Account } from '@ledgerhq/wallet-common/lib/types' -import { getFiatUnit } from '@ledgerhq/currencies' +import type { Account } from '@ledgerhq/live-common/lib/types' +import { getFiatCurrencyByTicker } from '@ledgerhq/live-common/lib/helpers/currencies' import Chart from 'components/base/Chart' import Box, { Card } from 'components/base/Box' @@ -30,7 +30,7 @@ const BalanceSummary = ({ renderHeader, selectedTime, }: Props) => { - const unit = getFiatUnit(counterValue) + const unit = getFiatCurrencyByTicker(counterValue).units[0] return ( { - const { ticker } = props + const { ticker, value, date } = props // TODO: in wallet-common, stop using currency. // always use ticker and remove that hack @@ -36,13 +33,15 @@ const mapStateToProps = (state, props) => { console.warn('`currency` is deprecated in CounterValue. use `ticker` instead.') // eslint-disable-line no-console } - const counterValueCode = getCounterValueCode(state) - const counterValueUnit = getFiatUnit(counterValueCode) - const getCounterValue = calculateCounterValueSelector(state)(currency, counterValueUnit) + const counterValueCurrency = counterValueCurrencySelector(state) + const counterValue = + !counterValueCurrency || !currency + ? 0 + : calculateCounterValueSelector(state)(currency, counterValueCurrency)(value, date) return { - counterValueCode, - getCounterValue, + counterValueCurrency, + value: counterValue, } } @@ -53,10 +52,15 @@ class CounterValue extends PureComponent { } render() { - const { getCounterValue, counterValueCode, date, value, ...props } = this.props - const counterValue = getCounterValue(value, date) + const { value, counterValueCurrency, date, ...props } = this.props return ( - + ) } } diff --git a/src/components/CounterValue/stories.js b/src/components/CounterValue/stories.js index 8b48de26..0bffa520 100644 --- a/src/components/CounterValue/stories.js +++ b/src/components/CounterValue/stories.js @@ -1,7 +1,7 @@ // @flow import React from 'react' -import { getCurrencyByCoinType } from '@ledgerhq/currencies' +import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/helpers/currencies' import { storiesOf } from '@storybook/react' import { number } from '@storybook/addon-knobs' @@ -9,7 +9,7 @@ import CounterValue from 'components/CounterValue' const stories = storiesOf('Components', module) -const currency = getCurrencyByCoinType(0) +const currency = getCryptoCurrencyById('bitcoin') stories.add('CounterValue', () => ( diff --git a/src/components/CryptoCurrencyIcon.js b/src/components/CryptoCurrencyIcon.js new file mode 100644 index 00000000..843c223a --- /dev/null +++ b/src/components/CryptoCurrencyIcon.js @@ -0,0 +1,19 @@ +// @flow +import React, { PureComponent } from 'react' +import { getCryptoCurrencyIcon } from '@ledgerhq/live-common/lib/react' +import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types' + +type Props = { + currency: CryptoCurrency, + size: number, +} + +class CryptoCurrencyIcon extends PureComponent { + render() { + const { currency, size } = this.props + const IconCurrency = getCryptoCurrencyIcon(currency) + return IconCurrency ? : null + } +} + +export default CryptoCurrencyIcon diff --git a/src/components/DashboardPage/AccountCard.js b/src/components/DashboardPage/AccountCard.js index efbd3d72..8512f680 100644 --- a/src/components/DashboardPage/AccountCard.js +++ b/src/components/DashboardPage/AccountCard.js @@ -2,15 +2,15 @@ import React from 'react' import styled from 'styled-components' -import { getIconByCoinType } from '@ledgerhq/currencies/react' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import Chart from 'components/base/Chart' import Bar from 'components/base/Bar' import Box, { Card } from 'components/base/Box' import CalculateBalance from 'components/CalculateBalance' import FormattedVal from 'components/base/FormattedVal' +import CryptoCurrencyIcon from 'components/CryptoCurrencyIcon' const Wrapper = styled(Card).attrs({ p: 4, @@ -30,81 +30,74 @@ const AccountCard = ({ account: Account, onClick?: Function, daysCount: number, -}) => { - const Icon = getIconByCoinType(account.currency.coinType) - return ( - - - - - {Icon && } +}) => ( + + + + + + + + + {account.unit.code} + + + {account.name} - - - {account.unit.code} + + + + + + + + ( + + + + - - {account.name} + + - - - - - - ( - - - - - - - - - - - - )} - /> - - ) -} + )} + /> + +) AccountCard.defaultProps = { onClick: undefined, diff --git a/src/components/DashboardPage/index.js b/src/components/DashboardPage/index.js index 215f87ef..a115b29d 100644 --- a/src/components/DashboardPage/index.js +++ b/src/components/DashboardPage/index.js @@ -6,9 +6,12 @@ import { compose } from 'redux' import { translate } from 'react-i18next' import { connect } from 'react-redux' import { push } from 'react-router-redux' -import { formatCurrencyUnit, getFiatUnit } from '@ledgerhq/currencies' +import { + formatCurrencyUnit, + getFiatCurrencyByTicker, +} from '@ledgerhq/live-common/lib/helpers/currencies' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import chunk from 'lodash/chunk' @@ -94,9 +97,13 @@ class DashboardPage extends PureComponent { text: 'Total balance', color: colors.wallet, balance: { - counterValue: formatCurrencyUnit(getFiatUnit(counterValue), data.totalBalance, { - showCode: true, - }), + counterValue: formatCurrencyUnit( + getFiatCurrencyByTicker(counterValue).units[0], + data.totalBalance, + { + showCode: true, + }, + ), }, }) } diff --git a/src/components/DeviceCheckAddress.js b/src/components/DeviceCheckAddress.js index 1d9beff5..dbf4bc23 100644 --- a/src/components/DeviceCheckAddress.js +++ b/src/components/DeviceCheckAddress.js @@ -3,7 +3,7 @@ import { PureComponent } from 'react' import { ipcRenderer } from 'electron' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { Device } from 'types/common' import { sendEvent } from 'renderer/events' diff --git a/src/components/DeviceConnect/index.js b/src/components/DeviceConnect/index.js index a4e25abd..7373804a 100644 --- a/src/components/DeviceConnect/index.js +++ b/src/components/DeviceConnect/index.js @@ -3,14 +3,14 @@ import React, { PureComponent } from 'react' import styled from 'styled-components' import { Trans, translate } from 'react-i18next' -import { getCurrencyByCoinType } from '@ledgerhq/currencies' -import { getIconByCoinType } from '@ledgerhq/currencies/react' +import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types' import type { T, Device, Devices } from 'types/common' import noop from 'lodash/noop' import Box from 'components/base/Box' +import CryptoCurrencyIcon from 'components/CryptoCurrencyIcon' import IconCheck from 'icons/Check' import IconExclamationCircle from 'icons/ExclamationCircle' @@ -138,7 +138,7 @@ StepCheck.defaultProps = { type Props = { accountName: null | string, appOpened: null | 'success' | 'fail', - coinType: number, + currency: CryptoCurrency, devices: Devices, deviceSelected: Device | null, onChangeDevice: Function, @@ -180,16 +180,13 @@ class DeviceConnect extends PureComponent { } render() { - const { deviceSelected, accountName, coinType, t, onChangeDevice, devices } = this.props + const { deviceSelected, accountName, currency, t, onChangeDevice, devices } = this.props const appState = this.getAppState() const hasDevice = devices.length > 0 const hasMultipleDevices = devices.length > 1 - const { name: appName } = getCurrencyByCoinType(coinType) - const IconCurrency = getIconByCoinType(coinType) - return ( @@ -240,13 +237,13 @@ class DeviceConnect extends PureComponent { - + {'Open '} - {appName} + {currency.name} {' App on your device'} diff --git a/src/components/DeviceMonit/index.js b/src/components/DeviceMonit/index.js index 6cf55ed9..c6b06ca7 100644 --- a/src/components/DeviceMonit/index.js +++ b/src/components/DeviceMonit/index.js @@ -3,7 +3,7 @@ import React, { PureComponent } from 'react' import { connect } from 'react-redux' import { ipcRenderer } from 'electron' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import { sendEvent } from 'renderer/events' import { getCurrentDevice } from 'reducers/devices' diff --git a/src/components/DeviceMonitNew/index.js b/src/components/DeviceMonitNew/index.js index 193b69d0..7aeb5f20 100644 --- a/src/components/DeviceMonitNew/index.js +++ b/src/components/DeviceMonitNew/index.js @@ -4,7 +4,7 @@ import { PureComponent } from 'react' import { connect } from 'react-redux' import { ipcRenderer } from 'electron' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account, CryptoCurrency } from '@ledgerhq/live-common/lib/types' import type { Device, Devices } from 'types/common' import { sendEvent } from 'renderer/events' @@ -19,7 +19,7 @@ type DeviceStatus = 'unconnected' | 'connected' type AppStatus = 'success' | 'fail' | 'progress' type Props = { - coinType: number, + currency: ?CryptoCurrency, devices: Devices, deviceSelected: Device | null, account?: Account, @@ -78,7 +78,7 @@ class DeviceMonit extends PureComponent { } checkAppOpened = () => { - const { deviceSelected, account, coinType } = this.props + const { deviceSelected, account, currency } = this.props if (deviceSelected === null) { return @@ -93,9 +93,9 @@ class DeviceMonit extends PureComponent { } } - if (coinType) { + if (currency) { options = { - coinType, + currencyId: currency.id, } } @@ -134,13 +134,13 @@ class DeviceMonit extends PureComponent { } render() { - const { coinType, account, devices, deviceSelected, render } = this.props + const { currency, account, devices, deviceSelected, render } = this.props const { appStatus, deviceStatus } = this.state if (render) { return render({ appStatus, - coinType: account ? account.coinType : coinType, + currency: account ? account.currency : currency, devices, deviceSelected: deviceStatus === 'connected' ? deviceSelected : null, deviceStatus, diff --git a/src/components/IsUnlocked.js b/src/components/IsUnlocked.js index 95ffec9b..c2da407b 100644 --- a/src/components/IsUnlocked.js +++ b/src/components/IsUnlocked.js @@ -6,7 +6,7 @@ import { connect } from 'react-redux' import { compose } from 'redux' import styled from 'styled-components' import { translate } from 'react-i18next' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { Settings, T } from 'types/common' import IconLockScreen from 'icons/LockScreen' diff --git a/src/components/OperationsList/Operation.js b/src/components/OperationsList/Operation.js index 21ab2c0e..c3baafd1 100644 --- a/src/components/OperationsList/Operation.js +++ b/src/components/OperationsList/Operation.js @@ -5,9 +5,9 @@ import { connect } from 'react-redux' import styled from 'styled-components' import moment from 'moment' import noop from 'lodash/noop' -import { getIconByCoinType } from '@ledgerhq/currencies/react' +import { getCryptoCurrencyIcon } from '@ledgerhq/live-common/lib/react' -import type { Account, Operation as OperationType } from '@ledgerhq/wallet-common/lib/types' +import type { Account, Operation as OperationType } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' @@ -130,7 +130,7 @@ class Operation extends PureComponent { } = this.props const { unit, currency } = account const time = moment(op.date) - const Icon = getIconByCoinType(account.currency.coinType) + const Icon = getCryptoCurrencyIcon(account.currency) const isNegative = op.amount < 0 const type = !isNegative ? 'from' : 'to' diff --git a/src/components/OperationsList/index.js b/src/components/OperationsList/index.js index 4d31a567..b8db8fbc 100644 --- a/src/components/OperationsList/index.js +++ b/src/components/OperationsList/index.js @@ -9,9 +9,9 @@ import { translate } from 'react-i18next' import { groupAccountOperationsByDay, groupAccountsOperationsByDay, -} from '@ledgerhq/wallet-common/lib/helpers/account' +} from '@ledgerhq/live-common/lib/helpers/account' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import noop from 'lodash/noop' import keyBy from 'lodash/keyBy' diff --git a/src/components/OperationsList/stories.js b/src/components/OperationsList/stories.js index b144eac1..b8237619 100644 --- a/src/components/OperationsList/stories.js +++ b/src/components/OperationsList/stories.js @@ -1,7 +1,7 @@ // @flow import React from 'react' -import { genAccount } from '@ledgerhq/wallet-common/lib/mock/account' +import { genAccount } from '@ledgerhq/live-common/lib/mock/account' import { storiesOf } from '@storybook/react' import { boolean } from '@storybook/addon-knobs' diff --git a/src/components/QRCodeExporter.js b/src/components/QRCodeExporter.js index 21ee4f90..3a4a3510 100644 --- a/src/components/QRCodeExporter.js +++ b/src/components/QRCodeExporter.js @@ -19,7 +19,7 @@ function makeChunks(state: State): Array { 'account', account.id, account.name, - account.coinType, + account.currency.id, ]), ] return data.map((arr, i) => JSON.stringify([data.length, i, ...arr])) diff --git a/src/components/ReceiveBox.js b/src/components/ReceiveBox.js index cfb6b0a9..d0fb9340 100644 --- a/src/components/ReceiveBox.js +++ b/src/components/ReceiveBox.js @@ -4,7 +4,7 @@ import React, { PureComponent } from 'react' import { connect } from 'react-redux' import styled from 'styled-components' import { ipcRenderer } from 'electron' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { Device } from 'types/common' diff --git a/src/components/RequestAmount/index.js b/src/components/RequestAmount/index.js index b037f75f..12ec263f 100644 --- a/src/components/RequestAmount/index.js +++ b/src/components/RequestAmount/index.js @@ -5,12 +5,11 @@ import { compose } from 'redux' import { translate } from 'react-i18next' import styled from 'styled-components' import { connect } from 'react-redux' -import type { Account, CalculateCounterValue } from '@ledgerhq/wallet-common/lib/types' -import type { FiatUnit } from '@ledgerhq/currencies' +import type { Currency, Account, CalculateCounterValue } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' -import { getCounterValueFiatUnit } from 'reducers/settings' +import { counterValueCurrencySelector } from 'reducers/settings' import { calculateCounterValueSelector, reverseCounterValueSelector } from 'reducers/counterValues' import InputCurrency from 'components/base/InputCurrency' @@ -36,7 +35,7 @@ const InputCenter = styled(Box).attrs({ ` const mapStateToProps = state => ({ - rightUnit: getCounterValueFiatUnit(state), + rightCurrency: counterValueCurrencySelector(state), getCounterValue: calculateCounterValueSelector(state), getReverseCounterValue: reverseCounterValueSelector(state), }) @@ -59,7 +58,7 @@ type Props = { // used to determine the right input unit // retrieved via selector (take the chosen countervalue unit) - rightUnit: FiatUnit, + rightCurrency: Currency, // used to calculate the opposite field value (right & left) getCounterValue: CalculateCounterValue, @@ -80,19 +79,19 @@ export class RequestAmount extends PureComponent { } handleChangeAmount = (changedField: string) => (val: number) => { - const { rightUnit, getReverseCounterValue, account, max, onChange } = this.props + const { rightCurrency, getReverseCounterValue, account, max, onChange } = this.props if (changedField === 'left') { onChange(val > max ? max : val) } else if (changedField === 'right') { - const leftVal = getReverseCounterValue(account.currency, rightUnit)(val) + const leftVal = getReverseCounterValue(account.currency, rightCurrency)(val) onChange(leftVal > max ? max : leftVal) } } renderInputs(containerProps: Object) { - const { value, account, rightUnit, getCounterValue } = this.props - const right = getCounterValue(account.currency, rightUnit)(value) - + const { value, account, rightCurrency, getCounterValue } = this.props + const right = getCounterValue(account.currency, rightCurrency)(value) + const rightUnit = rightCurrency.units[0] return ( ({ }) const renderItem = a => { - const Icon = getIconByCoinType(a.coinType) + const Icon = getCryptoCurrencyIcon(a) const { color } = a.currency return ( diff --git a/src/components/SelectAccount/stories.js b/src/components/SelectAccount/stories.js index 18190db9..e0dc7bf8 100644 --- a/src/components/SelectAccount/stories.js +++ b/src/components/SelectAccount/stories.js @@ -2,35 +2,13 @@ import React, { Component } from 'react' import { storiesOf } from '@storybook/react' -import Chance from 'chance' -import { getCurrencyByCoinType, getDefaultUnitByCoinType } from '@ledgerhq/currencies' +import { genAccount } from '@ledgerhq/live-common/lib/mock/account' import { SelectAccount } from 'components/SelectAccount' -const chance = new Chance() const stories = storiesOf('Components', module) -export const accounts = [...Array(20)].map(() => ({ - id: chance.string(), - address: chance.string({ - pool: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', - length: 30, - }), - addresses: [], - balance: chance.integer({ min: 10000000000, max: 2000000000000 }), - balanceByDay: {}, - coinType: 1, - currency: getCurrencyByCoinType(1), - index: chance.integer({ min: 0, max: 20 }), - name: chance.name(), - path: '', - rootPath: '', - operations: [], - unit: getDefaultUnitByCoinType(1), - settings: { - minConfirmations: 2, - }, -})) +export const accounts = [...Array(20)].map((_, i) => genAccount(i)) class Wrapper extends Component { state = { diff --git a/src/components/SelectCurrency/index.js b/src/components/SelectCurrency/index.js index 298a90e9..249b0cb5 100644 --- a/src/components/SelectCurrency/index.js +++ b/src/components/SelectCurrency/index.js @@ -2,27 +2,24 @@ import React from 'react' import { translate } from 'react-i18next' -import { getIconByCoinType } from '@ledgerhq/currencies/react' -import { listCurrencies } from '@ledgerhq/currencies' +import { listCryptoCurrencies } from '@ledgerhq/live-common/lib/helpers/currencies' import noop from 'lodash/noop' -import type { Currency } from '@ledgerhq/currencies' +import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' +import CryptoCurrencyIcon from 'components/CryptoCurrencyIcon' import Select from 'components/base/Select' import Box from 'components/base/Box' -const renderItem = a => { - const { color, name, coinType } = a - const Icon = getIconByCoinType(coinType) +const renderItem = (currency: CryptoCurrency) => { + const { color, name } = currency return ( - {Icon && ( - - - - )} + + + {name} @@ -30,23 +27,24 @@ const renderItem = a => { ) } -const currencies = listCurrencies() +const currencies = listCryptoCurrencies().sort((a, b) => a.name.localeCompare(b.name)) type Props = { onChange: Function, - value?: Currency, + value?: CryptoCurrency, + placeholder: string, t: T, } -const SelectCurrency = ({ onChange, value, t, ...props }: Props) => ( +const SelectCurrency = ({ onChange, value, t, placeholder, ...props }: Props) => ( props.onChangeCurrency(item.data)} - renderSelected={item => item.name} - items={currencies} - value={ - props.currency ? currencies.find(c => c.key === get(props, 'currency.coinType')) : null - } + onChange={props.onChangeCurrency} + value={props.currency} /> ) diff --git a/src/components/modals/AddAccount/03-step-import.js b/src/components/modals/AddAccount/03-step-import.js index 54892def..36d6a492 100644 --- a/src/components/modals/AddAccount/03-step-import.js +++ b/src/components/modals/AddAccount/03-step-import.js @@ -2,10 +2,8 @@ import React, { Fragment } from 'react' import styled from 'styled-components' -import { getDefaultUnitByCoinType } from '@ledgerhq/currencies' -import type { Currency } from '@ledgerhq/currencies/lib/types' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { CryptoCurrency, Account } from '@ledgerhq/live-common/lib/types' import Box from 'components/base/Box' @@ -29,7 +27,7 @@ const AccountItem = styled(AccountCard)` type Props = { accountsImport: Object, archivedAccounts: Account[], - currency: Currency | null, + currency?: ?CryptoCurrency, importProgress: boolean, onSelectAccount?: Function, selectedAccounts?: Array, @@ -37,7 +35,7 @@ type Props = { function StepImport(props: Props) { const hasAccountsImports = Object.keys(props.accountsImport).length > 0 - const unit = props.currency !== null && getDefaultUnitByCoinType(props.currency.coinType) + const unit = props.currency && props.currency.units[0] return ( {props.importProgress ? ( @@ -56,7 +54,7 @@ function StepImport(props: Props) { onClick={props.onSelectAccount && props.onSelectAccount(a.id)} account={{ ...a, - coinType: props.currency && props.currency.coinType, + currencyId: props.currency && props.currency.id, name: `Account ${a.accountIndex}`, currency: props.currency, unit, diff --git a/src/components/modals/AddAccount/index.js b/src/components/modals/AddAccount/index.js index 0e70faed..026ac573 100644 --- a/src/components/modals/AddAccount/index.js +++ b/src/components/modals/AddAccount/index.js @@ -5,10 +5,8 @@ import { connect } from 'react-redux' import { compose } from 'redux' import { translate } from 'react-i18next' import { ipcRenderer } from 'electron' -import { getDefaultUnitByCoinType } from '@ledgerhq/currencies' -import type { Account } from '@ledgerhq/wallet-common/lib/types' -import type { Currency } from '@ledgerhq/currencies' +import type { Account, CryptoCurrency } from '@ledgerhq/live-common/lib/types' import type { Device, T } from 'types/common' @@ -63,11 +61,11 @@ type Props = { type State = { accountsImport: Object, - currency: Currency | null, - deviceSelected: Device | null, + currency: ?CryptoCurrency, + deviceSelected: ?Device, fetchingCounterValues: boolean, selectedAccounts: Array, - appStatus: null | string, + appStatus: ?string, stepIndex: number, } @@ -107,13 +105,13 @@ class AddAccountModal extends PureComponent { const { accounts } = this.props const { deviceSelected, currency } = this.state - if (deviceSelected === null || currency === null) { + if (!deviceSelected || !currency) { return } sendEvent('usb', 'wallet.getAccounts', { pathDevice: deviceSelected.path, - coinType: currency.coinType, + currencyId: currency.id, currentAccounts: accounts.map(acc => acc.id), }) } @@ -201,7 +199,7 @@ class AddAccountModal extends PureComponent { name: `Account ${accountIndex + 1}`, archived: true, currency, - unit: getDefaultUnitByCoinType(currency.coinType), + unit: currency.units[0], }) } } @@ -223,7 +221,7 @@ class AddAccountModal extends PureComponent { : [a, ...prev.selectedAccounts], })) - handleChangeCurrency = (currency: Currency) => this.setState({ currency }) + handleChangeCurrency = (currency: CryptoCurrency) => this.setState({ currency }) handleChangeStatus = (deviceStatus, appStatus) => this.setState({ appStatus }) diff --git a/src/components/modals/OperationDetails.js b/src/components/modals/OperationDetails.js index ccbbc8db..48715240 100644 --- a/src/components/modals/OperationDetails.js +++ b/src/components/modals/OperationDetails.js @@ -7,7 +7,7 @@ import { translate } from 'react-i18next' import styled from 'styled-components' import moment from 'moment' -import type { Account, Operation } from '@ledgerhq/wallet-common/lib/types' +import type { Account, Operation } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' import { MODAL_OPERATION_DETAILS } from 'config/constants' diff --git a/src/components/modals/Receive/01-step-account.js b/src/components/modals/Receive/01-step-account.js index 258653fd..049401f8 100644 --- a/src/components/modals/Receive/01-step-account.js +++ b/src/components/modals/Receive/01-step-account.js @@ -2,7 +2,7 @@ import React from 'react' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' import Box from 'components/base/Box' diff --git a/src/components/modals/Receive/03-step-confirm-address.js b/src/components/modals/Receive/03-step-confirm-address.js index 3c008b01..2f205e1b 100644 --- a/src/components/modals/Receive/03-step-confirm-address.js +++ b/src/components/modals/Receive/03-step-confirm-address.js @@ -3,7 +3,7 @@ import React, { Fragment } from 'react' import styled from 'styled-components' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { Device, T } from 'types/common' import Box from 'components/base/Box' diff --git a/src/components/modals/Receive/04-step-receive-funds.js b/src/components/modals/Receive/04-step-receive-funds.js index efe220f7..a913b8a7 100644 --- a/src/components/modals/Receive/04-step-receive-funds.js +++ b/src/components/modals/Receive/04-step-receive-funds.js @@ -2,7 +2,7 @@ import React from 'react' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' import Box from 'components/base/Box' diff --git a/src/components/modals/Receive/index.js b/src/components/modals/Receive/index.js index da74514f..a7029775 100644 --- a/src/components/modals/Receive/index.js +++ b/src/components/modals/Receive/index.js @@ -3,7 +3,7 @@ import React, { Fragment, PureComponent } from 'react' import { translate } from 'react-i18next' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { T, Device } from 'types/common' import { MODAL_RECEIVE } from 'config/constants' diff --git a/src/components/modals/Send/01-step-amount.js b/src/components/modals/Send/01-step-amount.js index 67c61e71..628ac7ad 100644 --- a/src/components/modals/Send/01-step-amount.js +++ b/src/components/modals/Send/01-step-amount.js @@ -1,7 +1,7 @@ // @flow import React, { Fragment } from 'react' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' diff --git a/src/components/modals/Send/03-step-verification.js b/src/components/modals/Send/03-step-verification.js index 2b243202..5dcb5edf 100644 --- a/src/components/modals/Send/03-step-verification.js +++ b/src/components/modals/Send/03-step-verification.js @@ -9,7 +9,7 @@ import { multiline } from 'styles/helpers' import DeviceCheckAddress from 'components/DeviceCheckAddress' import DeviceConfirm from 'components/DeviceConfirm' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { Device, T } from 'types/common' const Container = styled(Box).attrs({ diff --git a/src/components/modals/Send/Footer.js b/src/components/modals/Send/Footer.js index 162f2848..b5bf5220 100644 --- a/src/components/modals/Send/Footer.js +++ b/src/components/modals/Send/Footer.js @@ -1,7 +1,7 @@ // @flow import React from 'react' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' diff --git a/src/components/modals/Send/index.js b/src/components/modals/Send/index.js index 3cad47ee..47f354e9 100644 --- a/src/components/modals/Send/index.js +++ b/src/components/modals/Send/index.js @@ -5,7 +5,7 @@ import { translate } from 'react-i18next' import { connect } from 'react-redux' import { compose } from 'redux' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { T, Device } from 'types/common' import { getVisibleAccounts } from 'reducers/accounts' diff --git a/src/components/modals/SettingsAccount.js b/src/components/modals/SettingsAccount.js index 8bca9901..e5abc368 100644 --- a/src/components/modals/SettingsAccount.js +++ b/src/components/modals/SettingsAccount.js @@ -4,7 +4,7 @@ import React, { PureComponent } from 'react' import { connect } from 'react-redux' import get from 'lodash/get' import { push } from 'react-router-redux' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import { MODAL_SETTINGS_ACCOUNT } from 'config/constants' diff --git a/src/components/modals/StepConnectDevice.js b/src/components/modals/StepConnectDevice.js index 08ec1e47..69198f31 100644 --- a/src/components/modals/StepConnectDevice.js +++ b/src/components/modals/StepConnectDevice.js @@ -2,8 +2,7 @@ import React from 'react' -import type { Account } from '@ledgerhq/wallet-common/lib/types' -import type { Currency } from '@ledgerhq/currencies/lib/types' +import type { Account, CryptoCurrency } from '@ledgerhq/live-common/lib/types' import type { Device } from 'types/common' import DeviceConnect from 'components/DeviceConnect' @@ -12,7 +11,7 @@ import DeviceMonit from 'components/DeviceMonitNew' type Props = { accountName?: string, account?: ?Account, - currency?: ?Currency, + currency?: ?CryptoCurrency, deviceSelected: ?Device, onChangeDevice: Function, onStatusChange: Function, @@ -21,13 +20,13 @@ type Props = { const StepConnectDevice = (props: Props) => ( ( + render={({ currency, appStatus, devices, deviceSelected }) => ( ( /> ) -StepConnectDevice.defaultProps = { - accountName: undefined, - account: undefined, - currency: undefined, -} - export default StepConnectDevice diff --git a/src/helpers/__tests__/balance.test.js b/src/helpers/__tests__/balance.test.js deleted file mode 100644 index e1614ac7..00000000 --- a/src/helpers/__tests__/balance.test.js +++ /dev/null @@ -1,137 +0,0 @@ -import { getBalanceHistoryForAccount, getBalanceHistoryForAccounts } from 'helpers/balance' - -const counterValues = { - BTC: { - USD: { - '2018-01-01': 1, - '2018-01-02': 2, - '2018-01-03': 3, - '2018-01-04': 4, - '2018-01-05': 5, - }, - }, -} - -describe('helpers > balance', () => { - describe('getBalanceHistoryForAccount', () => { - test('should handle a simple case', () => { - const account = { - coinType: 0, - balanceByDay: { - '2018-01-01': 1, - '2018-01-02': 2, - }, - } - - const interval = { - start: '2018-01-01', - end: '2018-01-02', - } - - const balances = getBalanceHistoryForAccount({ - counterValue: 'USD', - account, - counterValues, - interval, - }) - - expect(balances).toEqual([ - { date: '2018-01-01', balance: 1 }, - { date: '2018-01-02', balance: 4 }, - ]) - }) - - test('should handle empty days', () => { - const account = { - coinType: 0, - balanceByDay: { - '2018-01-01': 1, - '2018-01-03': 2, - }, - } - - const interval = { - start: '2018-01-01', - end: '2018-01-03', - } - - const balances = getBalanceHistoryForAccount({ - counterValue: 'USD', - account, - counterValues, - interval, - }) - - expect(balances).toEqual([ - { date: '2018-01-01', balance: 1 }, - { date: '2018-01-02', balance: 2 }, - { date: '2018-01-03', balance: 6 }, - ]) - }) - - test('should work if interval dont contain operations', () => { - const account = { - coinType: 0, - balanceByDay: { - '2018-01-01': 1, - }, - } - - const interval = { - start: '2018-01-02', - end: '2018-01-03', - } - - const balances = getBalanceHistoryForAccount({ - counterValue: 'USD', - account, - counterValues, - interval, - }) - - expect(balances).toEqual([ - { date: '2018-01-02', balance: 2 }, - { date: '2018-01-03', balance: 3 }, - ]) - }) - }) - - describe('getBalanceHistoryForAccounts', () => { - test('should merge multiple accounts balance', () => { - const account1 = { - coinType: 0, - balanceByDay: { - '2018-01-01': 1, - '2018-01-02': 2, - }, - } - - const account2 = { - coinType: 0, - balanceByDay: { - '2018-01-02': 5, - '2018-01-04': 6, - }, - } - - const interval = { - start: '2018-01-01', - end: '2018-01-04', - } - - const balances = getBalanceHistoryForAccounts({ - counterValue: 'USD', - accounts: [account1, account2], - counterValues, - interval, - }) - - expect(balances).toEqual([ - { date: '2018-01-01', balance: 1 }, - { date: '2018-01-02', balance: 14 }, - { date: '2018-01-03', balance: 21 }, - { date: '2018-01-04', balance: 32 }, - ]) - }) - }) -}) diff --git a/src/helpers/balance.js b/src/helpers/balance.js index cd12724a..1821394c 100644 --- a/src/helpers/balance.js +++ b/src/helpers/balance.js @@ -2,8 +2,7 @@ import moment from 'moment' import get from 'lodash/get' -import { getDefaultUnitByCoinType } from '@ledgerhq/currencies' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import find from 'lodash/find' import first from 'lodash/first' @@ -70,7 +69,7 @@ export function getBalanceHistoryForAccount({ interval: DateInterval, }): Array { const todayDate = moment().format('YYYY-MM-DD') - const unit = getDefaultUnitByCoinType(account.coinType) + const { unit } = account const counterVals = get(counterValues, `${unit.code}.${counterValue}`) let lastBalance = getBalanceAtIntervalStart(account, interval) return mapInterval(interval, date => { diff --git a/src/helpers/btc.js b/src/helpers/btc.js index 796525e0..bdef2643 100644 --- a/src/helpers/btc.js +++ b/src/helpers/btc.js @@ -1,9 +1,10 @@ // @flow +import { coinTypeForId } from 'internals/usb/wallet/accounts' import ledger from 'ledger-test-library' import bitcoin from 'bitcoinjs-lib' import axios from 'axios' -import type { OperationRaw } from '@ledgerhq/wallet-common/lib/types' +import type { OperationRaw } from '@ledgerhq/live-common/lib/types' import groupBy from 'lodash/groupBy' import noop from 'lodash/noop' @@ -11,16 +12,16 @@ import uniqBy from 'lodash/uniqBy' const GAP_LIMIT_ADDRESSES = 20 -export const networks = [ - { +export const networks = { + bitcoin: { ...bitcoin.networks.bitcoin, family: 1, }, - { + bitcoin_testnet: { ...bitcoin.networks.testnet, family: 1, }, -] +} export function computeOperation(addresses: Array, accountId: string) { return (t: Object) => { @@ -78,7 +79,7 @@ export async function getAccount({ hdnode, segwit, network, - coinType, + currencyId, accountId, asyncDelay = 250, onProgress = noop, @@ -89,7 +90,7 @@ export async function getAccount({ currentIndex?: number, hdnode: Object, segwit: boolean, - coinType: number, + currencyId: string, accountId: string, network: Object, asyncDelay?: number, @@ -156,7 +157,7 @@ export async function getAccount({ let txs = [] - const operationsOpts = { coin_type: coinType } + const operationsOpts = { coin_type: coinTypeForId(currencyId) } try { txs = await ledger.getTransactions(listAddresses, operationsOpts) @@ -204,7 +205,7 @@ export async function getAccount({ const account = { ...nextAddress, - coinType, + currencyId, addresses: operations.length > 0 ? allAddresses : [], balance, balanceByDay: getBalanceByDay(operations), diff --git a/src/helpers/db.js b/src/helpers/db.js index 086a1db3..f0aefed3 100644 --- a/src/helpers/db.js +++ b/src/helpers/db.js @@ -47,6 +47,7 @@ export default { } }, + // TODO flowtype this. we should be able to express all the possible entries and their expected type (with a union type) get: (key: DBKey, defaults: any): any => { const db = store(key) const data = db.get('data', defaults) diff --git a/src/internals/usb/wallet/accounts.js b/src/internals/usb/wallet/accounts.js index 7abe412a..4670719e 100644 --- a/src/internals/usb/wallet/accounts.js +++ b/src/internals/usb/wallet/accounts.js @@ -9,8 +9,6 @@ import Btc from '@ledgerhq/hw-app-btc' import { getAccount, getHDNode, networks } from 'helpers/btc' import { serializeAccounts } from 'reducers/accounts' -type CoinType = number - async function sleep(delay, callback) { if (delay !== 0) { await new Promise(resolve => setTimeout(resolve, delay)) @@ -56,16 +54,24 @@ function encodeBase58Check(vchIn) { return bs58check.encode(Buffer.from(vchIn)) } +export function coinTypeForId(id: string) { + if (id === 'bitcoin_testnet') return 1 + if (id === 'bitcoin') return 0 + throw new Error('coinTypeForId is a hack and will disappear with libcore') +} + export function getPath({ - coinType, + currencyId, account, segwit = true, }: { - coinType: CoinType, + currencyId: string, account?: any, segwit: boolean, }) { - return `${segwit ? 49 : 44}'/${coinType}'${account !== undefined ? `/${account}'` : ''}` + return `${segwit ? 49 : 44}'/${coinTypeForId(currencyId)}'${ + account !== undefined ? `/${account}'` : '' + }` } export function verifyAddress({ @@ -86,20 +92,20 @@ export default async ({ transport, currentAccounts, onProgress, - coinType = 1, + currencyId = 'bitcoin_testnet', segwit = true, nextAccountDelay = 1e3, }: { transport: Object, currentAccounts: Array<*>, onProgress: Function, - coinType?: CoinType, + currencyId?: string, segwit?: boolean, nextAccountDelay?: number, }) => { const btc = new Btc(transport) - const network = networks[coinType] + const network = networks[currencyId] const [p2pkh, p2sh, fam] = [network.pubKeyHash, network.scriptHash, network.family].map(v => v.toString(16).padStart(4, 0), @@ -110,7 +116,7 @@ export default async ({ const getPublicKey = path => btc.getWalletPublicKey(path) let result = bitcoin.crypto.sha256( - await getPublicKey(getPath({ segwit, coinType })).then( + await getPublicKey(getPath({ segwit, currencyId })).then( ({ publicKey }) => new Uint8Array(parseHexString(getCompressPublicKey(publicKey))), ), ) @@ -139,7 +145,7 @@ export default async ({ } const getAllAccounts = async (currentAccount = 0, accounts = []) => { - const path = getPath({ segwit, coinType, account: currentAccount }) + const path = getPath({ segwit, currencyId, account: currentAccount }) const xpub58 = await getXpub58ByPath({ path, account: currentAccount, network }) if (currentAccounts.includes(xpub58)) { @@ -149,7 +155,7 @@ export default async ({ const hdnode = getHDNode({ xpub58, network }) const account = await getAccount({ asyncDelay: 0, - coinType, + currencyId, accountId: xpub58, hdnode, network, @@ -164,7 +170,6 @@ export default async ({ accounts.push({ id: xpub58, - coinType, ...account, }) diff --git a/src/internals/usb/wallet/index.js b/src/internals/usb/wallet/index.js index 4af6e484..07285205 100644 --- a/src/internals/usb/wallet/index.js +++ b/src/internals/usb/wallet/index.js @@ -5,12 +5,11 @@ import Btc from '@ledgerhq/hw-app-btc' import getAllAccounts, { getPath, verifyAddress } from './accounts' -async function getAllAccountsByCoinType({ pathDevice, coinType, currentAccounts, onProgress }) { +async function getAllAccountsByCurrencyId({ pathDevice, currencyId, currentAccounts, onProgress }) { const transport = await CommNodeHid.open(pathDevice) - // 1: BTC Testnet - if (coinType === 1) { - return getAllAccounts({ coinType, transport, currentAccounts, onProgress }) + if (currencyId === 'bitcoin_testnet') { + return getAllAccounts({ currencyId, transport, currentAccounts, onProgress }) } throw new Error('Invalid coinType') @@ -19,11 +18,11 @@ async function getAllAccountsByCoinType({ pathDevice, coinType, currentAccounts, export default (sendEvent: Function) => ({ getAccounts: async ({ pathDevice, - coinType, + currencyId, currentAccounts, }: { pathDevice: string, - coinType: number, + currencyId: string, currentAccounts: Array, }) => { sendEvent( @@ -35,9 +34,9 @@ export default (sendEvent: Function) => ({ ) try { - const data = await getAllAccountsByCoinType({ + const data = await getAllAccountsByCurrencyId({ pathDevice, - coinType, + currencyId, currentAccounts, onProgress: progress => sendEvent('wallet.getAccounts.progress', progress, { kill: false }), }) @@ -59,13 +58,13 @@ export default (sendEvent: Function) => ({ } }, checkIfAppOpened: async ({ - coinType, + currencyId, devicePath, accountPath, accountAddress, segwit = true, }: { - coinType?: number, + currencyId?: string, devicePath: string, accountPath: string, accountAddress: string, @@ -82,9 +81,8 @@ export default (sendEvent: Function) => ({ throw new Error('Address is different') } } - - if (coinType) { - await btc.getWalletPublicKey(getPath({ coinType, segwit }), false, segwit) + if (currencyId) { + await btc.getWalletPublicKey(getPath({ currencyId, segwit }), false, segwit) sendEvent('wallet.checkIfAppOpened.success', { devicePath }) } } catch (err) { diff --git a/src/main/counterValuesSync.js b/src/main/counterValuesSync.js index d1419810..6a49280a 100644 --- a/src/main/counterValuesSync.js +++ b/src/main/counterValuesSync.js @@ -1,6 +1,6 @@ // @flow -import { fetchCurrentRates } from '@ledgerhq/wallet-common/lib/api/countervalue' +import { fetchCurrentRates } from '@ledgerhq/live-common/lib/api/countervalue' type SendFunction = (type: string, data: *) => void diff --git a/src/reducers/accounts.js b/src/reducers/accounts.js index 13c75218..a22c8f5d 100644 --- a/src/reducers/accounts.js +++ b/src/reducers/accounts.js @@ -1,12 +1,13 @@ // @flow +import { createSelector } from 'reselect' import { handleActions } from 'redux-actions' -import { createAccountModel } from '@ledgerhq/wallet-common/lib/models/account' +import { createAccountModel } from '@ledgerhq/live-common/lib/models/account' import every from 'lodash/every' import get from 'lodash/get' import reduce from 'lodash/reduce' -import type { Account } from '@ledgerhq/wallet-common/lib/types' +import type { Account } from '@ledgerhq/live-common/lib/types' import type { State } from 'reducers' @@ -58,7 +59,32 @@ const handlers: Object = { // Selectors +export function accountsSelector(state: { accounts: AccountsState }): Account[] { + return state.accounts +} + +export const archivedAccountsSelector = createSelector(accountsSelector, accounts => + accounts.filter(acc => acc.archived), +) + +export const visibleAccountsSelector = createSelector(accountsSelector, accounts => + accounts.filter(acc => !acc.archived), +) + +export const currenciesSelector = createSelector(visibleAccountsSelector, accounts => + [...new Set(accounts.map(a => a.currency))].sort((a, b) => a.name.localeCompare(b.name)), +) + +export const accountSelector = createSelector( + accountsSelector, + (_, { accountId }: { accountId: string }) => accountId, + (accounts, accountId) => accounts.find(a => a.id === accountId), +) + +// TODO remove deprecated selectors + export function getTotalBalance(state: { accounts: AccountsState }) { + // TODO we will have it using utility functions return reduce( state.accounts, (result, account) => { diff --git a/src/reducers/counterValues.js b/src/reducers/counterValues.js index 612a3f9e..965b4db3 100644 --- a/src/reducers/counterValues.js +++ b/src/reducers/counterValues.js @@ -7,9 +7,9 @@ import { makeCalculateCounterValue, makeReverseCounterValue, formatCounterValueDay, -} from '@ledgerhq/wallet-common/lib/helpers/countervalue' +} from '@ledgerhq/live-common/lib/helpers/countervalue' -import type { CalculateCounterValue } from '@ledgerhq/wallet-common/lib/types' +import type { CalculateCounterValue } from '@ledgerhq/live-common/lib/types' import type { State } from 'reducers' export type CounterValuesState = {} diff --git a/src/reducers/settings.js b/src/reducers/settings.js index 6ee647a0..8bd73282 100644 --- a/src/reducers/settings.js +++ b/src/reducers/settings.js @@ -1,15 +1,28 @@ // @flow import { handleActions } from 'redux-actions' -import { getFiatUnit } from '@ledgerhq/currencies' -import type { Currency } from '@ledgerhq/currencies' - -import get from 'lodash/get' +import { findCurrencyByTicker } from '@ledgerhq/live-common/lib/helpers/currencies' +import type { CryptoCurrency, Currency } from '@ledgerhq/live-common/lib/types' import type { Settings, CurrencySettings } from 'types/common' import type { State } from 'reducers' -export type SettingsState = Object +export type SettingsState = { + hasCompletedOnboarding: boolean, + username: string, + counterValue: string, + language: string, + orderAccounts: string, + password: { + isEnabled: boolean, + value: string, + }, + marketIndicator: string, + currenciesSettings: { + [currencyId: string]: CurrencySettings, + }, + region: string, +} const defaultState: SettingsState = { hasCompletedOnboarding: false, @@ -53,22 +66,25 @@ const handlers: Object = { }), } -export const hasPassword = (state: Object) => - get(state.settings, 'password.isEnabled', defaultState.password.isEnabled) +// TODO refactor selectors to *Selector naming convention + +export const hasPassword = (state: State): boolean => state.settings.password.isEnabled -export const getCounterValueCode = (state: Object) => - get(state.settings, 'counterValue', defaultState.counterValue) +export const getCounterValueCode = (state: State) => state.settings.counterValue -export const getCounterValueFiatUnit = (state: Object) => getFiatUnit(getCounterValueCode(state)) +export const counterValueCurrencySelector = (state: State): ?Currency => + findCurrencyByTicker(getCounterValueCode(state)) -export const getLanguage = (state: Object) => get(state.settings, 'language', defaultState.language) +export const getLanguage = (state: State) => state.settings.language -export const getOrderAccounts = (state: Object) => - get(state.settings, 'orderAccounts', defaultState.orderAccounts) +export const getOrderAccounts = (state: State) => state.settings.orderAccounts -export const currencySettingsSelector = (state: State, currency: Currency): CurrencySettings => { - const currencySettings = state.settings.currenciesSettings[currency.coinType] - return currencySettings || CURRENCY_DEFAULTS_SETTINGS +export const currencySettingsSelector = ( + state: State, + currency: CryptoCurrency, +): CurrencySettings => { + const currencySettings = state.settings.currenciesSettings[currency.id] + return { ...CURRENCY_DEFAULTS_SETTINGS, ...currencySettings } } export const marketIndicatorSelector = (state: State) => state.settings.marketIndicator diff --git a/src/renderer/events.js b/src/renderer/events.js index fe891861..7c258f0e 100644 --- a/src/renderer/events.js +++ b/src/renderer/events.js @@ -4,9 +4,8 @@ import { ipcRenderer } from 'electron' import objectPath from 'object-path' import debug from 'debug' import uniqBy from 'lodash/uniqBy' -import { getFiatUnit } from '@ledgerhq/currencies' -import type { Account } from '@ledgerhq/wallet-common/lib/types' -import type { Currency, Unit } from '@ledgerhq/currencies' +import { getFiatCurrencyByTicker } from '@ledgerhq/live-common/lib/helpers/currencies' +import type { Currency, Account } from '@ledgerhq/live-common/lib/types' import { CHECK_UPDATE_DELAY, SYNC_ACCOUNT_DELAY, SYNC_COUNTER_VALUES_DELAY } from 'config/constants' @@ -89,10 +88,10 @@ export function startSyncAccounts(accounts: Account[]) { syncAccountsInProgress = true sendEvent('accounts', 'sync.all', { accounts: accounts.map(account => { - const { id, coinType, rootPath, addresses, index, operations } = account + const { id, currency, rootPath, addresses, index, operations } = account return { id, - coinType, + currencyId: currency.id, allAddresses: addresses, currentIndex: index, rootPath, @@ -111,7 +110,7 @@ export function stopSyncAccounts() { export function startSyncCounterValues(counterValueCode: string, accounts: Account[]) { d.sync('Sync counterValues - start') const currencies: Currency[] = uniqBy(accounts.map(a => a.currency), 'code') - const counterValue: Unit = getFiatUnit(counterValueCode) + const counterValue = getFiatCurrencyByTicker(counterValueCode) sendEvent('msg', 'counterValues.sync', { currencies, counterValue }) } diff --git a/src/renderer/init.js b/src/renderer/init.js index 63a5acb4..99cce673 100644 --- a/src/renderer/init.js +++ b/src/renderer/init.js @@ -34,7 +34,7 @@ const rootNode = document.getElementById('app') store.dispatch(fetchSettings()) store.dispatch(initCounterValues()) -const state = store.getState() || {} +const state = store.getState() const language = getLanguage(state) const locked = isLocked(state) diff --git a/src/stories/currencies.stories.js b/src/stories/currencies.stories.js index 1917ab05..c3b5803f 100644 --- a/src/stories/currencies.stories.js +++ b/src/stories/currencies.stories.js @@ -2,21 +2,21 @@ import React, { Fragment } from 'react' import { storiesOf } from '@storybook/react' -import { listCurrencies } from '@ledgerhq/currencies' -import { getIconByCoinType } from '@ledgerhq/currencies/react' +import { listCryptoCurrencies } from '@ledgerhq/live-common/lib/helpers/currencies' +import { getCryptoCurrencyIcon } from '@ledgerhq/live-common/lib/react' -import type { Currency } from '@ledgerhq/currencies' +import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types' const stories = storiesOf('Common', module) -const currencies: Array = listCurrencies() +const currencies: Array = listCryptoCurrencies() stories.add('Currencies', () => (
- + @@ -25,10 +25,10 @@ stories.add('Currencies', () => ( {currencies.map(cur => { - const Icon = getIconByCoinType(cur.coinType) + const Icon = getCryptoCurrencyIcon(cur) return ( - - + +
{'coin type'}{'id'} {'name'} {'color'} {'icon'}
{cur.coinType}
{cur.id} {cur.name} {cur.color ? ( diff --git a/src/types/common.js b/src/types/common.js index 8fefd193..e12720f8 100644 --- a/src/types/common.js +++ b/src/types/common.js @@ -25,7 +25,7 @@ export type CurrencySettings = { } export type CurrenciesSettings = { - [coinType: number]: CurrencySettings, + [id: string]: CurrencySettings, } export type Settings = { diff --git a/yarn.lock b/yarn.lock index 6a0b1baa..420d7b32 100644 --- a/yarn.lock +++ b/yarn.lock @@ -956,14 +956,6 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" -"@ledgerhq/currencies@^4.10.1": - version "4.10.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/currencies/-/currencies-4.10.1.tgz#462081005e3e37e0737bad9aba189eef1663e96a" - dependencies: - lodash "^4.17.5" - numeral "^2.0.6" - querystring "^0.2.0" - "@ledgerhq/hw-app-btc@^4.7.3": version "4.7.3" resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-4.7.3.tgz#5a7d365f893f5a72bbb6b639d1738edced712c5f" @@ -990,14 +982,14 @@ dependencies: events "^2.0.0" -"@ledgerhq/wallet-common@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/wallet-common/-/wallet-common-1.2.0.tgz#5e648829b6dff0fe33f31da2ee4a974df405642e" +"@ledgerhq/live-common@^2.0.0-rc4": + version "2.0.0-rc4" + resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.0.0-rc4.tgz#5f1028ff3e52fc6bf7e42c5ea64d71be9b843f82" dependencies: - "@ledgerhq/currencies" "^4.10.1" axios "^0.18.0" invariant "^2.2.2" lodash "^4.17.4" + numeral "^2.0.6" prando "^3.0.1" react "^16.0.0" @@ -5018,7 +5010,7 @@ electron-webpack@^2.0.1: webpack-merge "^4.1.2" yargs "^11.1.0" -electron@1.8.4: +electron@1.8.4, electron@^1.8.2: version "1.8.4" resolved "https://registry.yarnpkg.com/electron/-/electron-1.8.4.tgz#cca8d0e6889f238f55b414ad224f03e03b226a38" dependencies: