From d015cdb067af19ca2c7ebe8cff5fc1b15ba18254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=ABck=20V=C3=A9zien?= Date: Thu, 25 Jan 2018 14:36:56 +0100 Subject: [PATCH] Update dependencies, fix sync Accounts, few clean --- flow-defs/process.js | 1 + package.json | 16 ++--- src/components/DashboardPage.js | 14 +++-- src/components/SideBar/Item.js | 2 +- src/components/SideBar/index.js | 32 ++++++---- src/components/UpdateNotifier.js | 9 ++- src/components/Wrapper.js | 2 +- src/components/base/Modal/index.js | 4 +- src/components/modals/AddAccount.js | 91 +++++++++++++++++----------- src/components/modals/Receive.js | 1 - src/components/modals/Send.js | 1 - src/constants.js | 2 + src/helpers/btc.js | 38 +++++++++--- src/i18n/en/translation.yml | 16 +++++ src/i18n/fr/translation.yml | 16 +++++ src/internals/index.js | 7 ++- src/internals/usb/devices.js | 4 +- src/internals/usb/wallet/accounts.js | 9 +-- src/main/app.js | 2 - src/main/bridge.js | 8 ++- src/main/index.js | 2 + src/reducers/accounts.js | 28 +++++++-- src/reducers/settings.js | 7 ++- src/renderer/events.js | 28 ++++++--- yarn.lock | 55 +++++++++-------- 25 files changed, 253 insertions(+), 142 deletions(-) create mode 100644 src/constants.js diff --git a/flow-defs/process.js b/flow-defs/process.js index 3a089aeb..37ad8d23 100644 --- a/flow-defs/process.js +++ b/flow-defs/process.js @@ -5,6 +5,7 @@ declare var process: { on(event: string, args: any): void, nextTick(callback: Function): void, setMaxListeners(any): void, + removeListener(string, Function): void, title: string, env: Object, } diff --git a/package.json b/package.json index 744b9d95..a14b291e 100644 --- a/package.json +++ b/package.json @@ -39,16 +39,16 @@ }, "dependencies": { "@ledgerhq/common": "2.0.5", - "@ledgerhq/hw-app-btc": "^2.0.5", - "@ledgerhq/hw-app-eth": "^2.0.5", - "@ledgerhq/hw-transport": "^2.0.5", - "@ledgerhq/hw-transport-node-hid": "^2.0.6", + "@ledgerhq/hw-app-btc": "^2.1.0", + "@ledgerhq/hw-app-eth": "^2.1.0", + "@ledgerhq/hw-transport": "^2.1.0", + "@ledgerhq/hw-transport-node-hid": "^2.1.0", "axios": "^0.17.1", "bcryptjs": "^2.4.3", "bitcoinjs-lib": "^3.3.2", "blockchain.info": "^2.11.0", "bs58check": "^2.1.1", - "color": "^2.0.1", + "color": "^3.0.0", "cross-env": "^5.1.3", "downshift": "^1.25.0", "electron-store": "^1.3.0", @@ -65,7 +65,7 @@ "raven-js": "^3.22.1", "react": "^16.2.0", "react-dom": "^16.2.0", - "react-i18next": "^7.3.1", + "react-i18next": "^7.3.2", "react-mortal": "^3.0.1", "react-motion": "^0.5.2", "react-redux": "^5.0.6", @@ -105,11 +105,11 @@ "eslint-config-airbnb": "^16.1.0", "eslint-config-prettier": "^2.9.0", "eslint-import-resolver-babel-module": "^4.0.0", - "eslint-plugin-flowtype": "^2.41.1", + "eslint-plugin-flowtype": "^2.42.0", "eslint-plugin-import": "^2.8.0", "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-react": "^7.5.1", - "flow-bin": "^0.63.1", + "flow-bin": "^0.64.0", "flow-typed": "^2.2.3", "husky": "^0.14.3", "lint-staged": "^6.0.0", diff --git a/src/components/DashboardPage.js b/src/components/DashboardPage.js index b7813210..2f2951fd 100644 --- a/src/components/DashboardPage.js +++ b/src/components/DashboardPage.js @@ -1,12 +1,14 @@ // @flow import React, { PureComponent } from 'react' +import { compose } from 'redux' +import { translate } from 'react-i18next' import { connect } from 'react-redux' import chunk from 'lodash/chunk' import { push } from 'react-router-redux' import type { MapStateToProps } from 'react-redux' -import type { Accounts } from 'types/common' +import type { Accounts, T } from 'types/common' import { format } from 'helpers/btc' @@ -29,6 +31,7 @@ const mapDispatchToProps = { } type Props = { + t: T, accounts: Accounts, push: Function, openModal: Function, @@ -53,7 +56,7 @@ class DashboardPage extends PureComponent { handleChangeTab = tab => this.setState({ tab }) render() { - const { totalBalance, openModal, push, accounts } = this.props + const { t, totalBalance, openModal, push, accounts } = this.props const { tab } = this.state const totalAccounts = Object.keys(accounts).length @@ -123,7 +126,7 @@ class DashboardPage extends PureComponent { style={{ borderStyle: 'dashed', cursor: 'pointer' }} onClick={() => openModal('add-account')} > - {'+ Add account'} + {`+ ${t('addAccount.title')}`} ) : ( { style={{ cursor: 'pointer', height: 200 }} onClick={() => push(`/account/${key}`)} > - {accounts[key].name} +
{accounts[key].name}
+
{accounts[key].data && format(accounts[key].data.balance)}
), )} @@ -144,4 +148,4 @@ class DashboardPage extends PureComponent { } } -export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage) +export default compose(connect(mapStateToProps, mapDispatchToProps), translate())(DashboardPage) diff --git a/src/components/SideBar/Item.js b/src/components/SideBar/Item.js index 6e21a70c..d433fca7 100644 --- a/src/components/SideBar/Item.js +++ b/src/components/SideBar/Item.js @@ -53,7 +53,7 @@ type Props = { linkTo?: string | null, modal?: string | null, desc?: string | null, - icon?: Element<*> | null, + icon?: string | null, location: Location, isModalOpened: boolean, push: Function, diff --git a/src/components/SideBar/index.js b/src/components/SideBar/index.js index e4f9fe4f..fd41b9b1 100644 --- a/src/components/SideBar/index.js +++ b/src/components/SideBar/index.js @@ -1,11 +1,13 @@ // @flow import React, { PureComponent } from 'react' +import { compose } from 'redux' +import { translate } from 'react-i18next' import styled from 'styled-components' import { connect } from 'react-redux' import type { MapStateToProps } from 'react-redux' -import type { Accounts } from 'types/common' +import type { Accounts, T } from 'types/common' import { openModal } from 'reducers/modals' import { getAccounts } from 'reducers/accounts' @@ -45,6 +47,7 @@ const BtnAddAccount = styled(Box).attrs({ ` type Props = { + t: T, accounts: Accounts, openModal: Function, } @@ -59,30 +62,30 @@ const mapDispatchToProps = { class SideBar extends PureComponent { render() { - const { accounts, openModal } = this.props + const { t, accounts, openModal } = this.props return ( - {'Menu'} + {t('sidebar.menu')}
- {'Dashboard'} + {t('dashboard.title')} - {'Send'} + {t('send.title')} - {'Receive'} + {t('receive.title')} - {'Settings'} + {t('settings.title')}
- {'Accounts'} + {t('sidebar.accounts')}
{Object.entries(accounts).map(([id, account]: [string, any]) => ( @@ -91,13 +94,18 @@ class SideBar extends PureComponent { ))}
- openModal('add-account')}>{'Add account'} + openModal('add-account')}> + {t('addAccount.title')} +
) } } -export default connect(mapStateToProps, mapDispatchToProps, null, { - pure: false, -})(SideBar) +export default compose( + connect(mapStateToProps, mapDispatchToProps, null, { + pure: false, + }), + translate(), +)(SideBar) diff --git a/src/components/UpdateNotifier.js b/src/components/UpdateNotifier.js index 22793776..3b7d3ba8 100644 --- a/src/components/UpdateNotifier.js +++ b/src/components/UpdateNotifier.js @@ -7,7 +7,7 @@ import type { MapStateToProps } from 'react-redux' import styled from 'styled-components' import { getUpdateStatus, getUpdateData } from 'reducers/update' -import { sendEvent } from 'renderer/events' +import { sendEvent, checkUpdates } from 'renderer/events' import type { State } from 'reducers' import type { UpdateStatus } from 'reducers/update' @@ -39,6 +39,12 @@ const Container = styled(Box).attrs({ ` class UpdateNotifier extends PureComponent { + componentWillReceiveProps(nextProps) { + if (['idle', 'unavailable', 'error'].includes(nextProps.updateStatus)) { + checkUpdates() + } + } + renderStatus() { const { updateStatus } = this.props switch (updateStatus) { @@ -68,6 +74,7 @@ class UpdateNotifier extends PureComponent { render() { const { updateStatus } = this.props + const isToggled = updateStatus === 'downloaded' return ( { - + {__PROD__ && } diff --git a/src/components/base/Modal/index.js b/src/components/base/Modal/index.js index 07abf42c..a4ee6a87 100644 --- a/src/components/base/Modal/index.js +++ b/src/components/base/Modal/index.js @@ -9,8 +9,6 @@ import Mortal from 'react-mortal' import styled from 'styled-components' import noop from 'lodash/noop' -import type { Element } from 'react' - import { rgba } from 'styles/helpers' import { closeModal, isModalOpened } from 'reducers/modals' @@ -139,7 +137,7 @@ export const ModalBody = ({ onClose, ...props }: { - children: Element | string, + children: any, onClose?: Function, }) => ( diff --git a/src/components/modals/AddAccount.js b/src/components/modals/AddAccount.js index ab92db2c..79ef0005 100644 --- a/src/components/modals/AddAccount.js +++ b/src/components/modals/AddAccount.js @@ -8,7 +8,7 @@ import type { MapStateToProps } from 'react-redux' import type { Accounts, Device } from 'types/common' import { closeModal } from 'reducers/modals' -import { getAccounts } from 'reducers/accounts' +import { canCreateAccount, getAccounts } from 'reducers/accounts' import { getCurrentDevice } from 'reducers/devices' import { sendEvent } from 'renderer/events' @@ -46,14 +46,18 @@ const Steps = { ), - connectDevice: () =>
Connect your Ledger
, - startWallet: (props: Object) =>
Select {props.wallet.toUpperCase()} App on your Ledger
, + connectDevice: (props: Object) => ( +
+
Connect your Ledger: {props.connected ? 'ok' : 'ko'}
+
Start {props.wallet.toUpperCase()} App on your Ledger: ko
+
+ ), inProgress: (props: Object) => (
In progress. @@ -65,20 +69,38 @@ const Steps = {
), listAccounts: (props: Object) => { - const accounts = Object.entries(props.accounts) + const accounts = [] + + let newAccount = null + + Object.entries(props.accounts).forEach(([, account]: [string, any]) => { + const hasTransactions = account.transactions.length > 0 + + if (hasTransactions) { + accounts.push(account) + } else { + newAccount = account + } + }) + return (
- {accounts.length > 0 - ? accounts.map(([index, account]: [string, any]) => ( -
-
Balance: {account.balance}
-
Transactions: {account.transactions.length}
-
- -
-
- )) - : 'No accounts'} + {accounts.map(account => ( +
+
Balance: {account.balance}
+
Transactions: {account.transactions.length}
+
+ +
+
+ ))} + {props.canCreateAccount && newAccount !== null ? ( +
+ +
+ ) : ( +
You cannot create new account
+ )}
) }, @@ -89,13 +111,14 @@ type InputValue = { wallet: string, } -type Step = 'createAccount' | 'connectDevice' | 'inProgress' | 'startWallet' | 'listAccounts' +type Step = 'createAccount' | 'connectDevice' | 'inProgress' | 'listAccounts' type Props = { + accounts: Accounts, addAccount: Function, + canCreateAccount: boolean, closeModal: Function, currentDevice: Device | null, - accounts: Accounts, } type State = { inputValue: InputValue, @@ -106,6 +129,7 @@ type State = { const mapStateToProps: MapStateToProps<*, *, *> = state => ({ accounts: getAccounts(state), + canCreateAccount: canCreateAccount(state), currentDevice: getCurrentDevice(state), }) @@ -133,21 +157,11 @@ class AddAccountModal extends PureComponent { ipcRenderer.on('msg', this.handleWalletRequest) } - componentWillReceiveProps(nextProps) { - const { currentDevice } = nextProps - - if (this.props.currentDevice === null && this.state.step !== 'createAccount') { - this.setState({ - step: currentDevice !== null ? 'startWallet' : 'connectDevice', - }) - } - } - componentDidUpdate() { const { step } = this.state const { currentDevice } = this.props - if (step === 'startWallet' && currentDevice !== null) { + if (step === 'connectDevice' && currentDevice !== null) { this.getWalletInfos() } else { clearTimeout(this._timeout) @@ -160,8 +174,8 @@ class AddAccountModal extends PureComponent { } getWalletInfos() { - const { inputValue } = this.state const { currentDevice, accounts } = this.props + const { inputValue } = this.state if (currentDevice === null) { return @@ -175,6 +189,7 @@ class AddAccountModal extends PureComponent { } getStepProps() { + const { currentDevice, canCreateAccount } = this.props const { inputValue, step, progress, accounts } = this.state const props = (predicate, props) => (predicate ? props : {}) @@ -185,7 +200,8 @@ class AddAccountModal extends PureComponent { onSubmit: this.handleSubmit, onChangeInput: this.handleChangeInput, }), - ...props(step === 'startWallet', { + ...props(step === 'connectDevice', { + connected: currentDevice !== null, wallet: inputValue.wallet, }), ...props(step === 'inProgress', { @@ -193,6 +209,7 @@ class AddAccountModal extends PureComponent { }), ...props(step === 'listAccounts', { accounts, + canCreateAccount, onAddAccount: this.handleAddAccount, }), } @@ -218,11 +235,11 @@ class AddAccountModal extends PureComponent { } } - handleAddAccount = index => () => { - const { inputValue, accounts } = this.state + handleAddAccount = account => () => { + const { inputValue } = this.state const { addAccount, closeModal } = this.props - const { id, ...data } = accounts[index] + const { id, ...data } = account addAccount({ id, @@ -232,6 +249,7 @@ class AddAccountModal extends PureComponent { }) closeModal('add-account') + this.handleClose() } @@ -246,7 +264,6 @@ class AddAccountModal extends PureComponent { handleSubmit = (e: SyntheticEvent) => { e.preventDefault() - const { currentDevice } = this.props const { inputValue } = this.state if (inputValue.accountName.trim() === '' || inputValue.wallet.trim() === '') { @@ -254,7 +271,7 @@ class AddAccountModal extends PureComponent { } this.setState({ - step: currentDevice === null ? 'connectDevice' : 'startWallet', + step: 'connectDevice', }) } @@ -275,7 +292,7 @@ class AddAccountModal extends PureComponent { return ( ( diff --git a/src/components/modals/Receive.js b/src/components/modals/Receive.js index a85e3e4d..23e9dbb0 100644 --- a/src/components/modals/Receive.js +++ b/src/components/modals/Receive.js @@ -11,7 +11,6 @@ class ReceiveModal extends PureComponent { return ( receive modal} /> ) diff --git a/src/components/modals/Send.js b/src/components/modals/Send.js index 164f636b..292ec8ef 100644 --- a/src/components/modals/Send.js +++ b/src/components/modals/Send.js @@ -149,7 +149,6 @@ class Send extends PureComponent { return ( ( diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 00000000..007c8a00 --- /dev/null +++ b/src/constants.js @@ -0,0 +1,2 @@ +export const CHECK_UPDATE_TIMEOUT = 5e3 +export const SYNC_ACCOUNT_TIMEOUT = 5e3 diff --git a/src/helpers/btc.js b/src/helpers/btc.js index 92802f1f..d47a04ed 100644 --- a/src/helpers/btc.js +++ b/src/helpers/btc.js @@ -84,6 +84,7 @@ export async function getAccount({ const script = segwit ? parseInt(network.scriptHash, 10) : parseInt(network.pubKeyHash, 10) let transactions = [] + let allAddresses = [] let lastAddress = null const pubKeyToSegwitAddress = (pubKey, scriptVersion) => { @@ -111,12 +112,15 @@ export async function getAccount({ }), }) - const getLastAddress = (addresses, lastTx) => { - const address = addresses - .filter(a => a.type === 'external') - .find(a => a.address === lastTx.addr) || { index: 0 } - - return getAddress({ type: 'external', index: address.index + 1 }) + const getLastAddress = (addresses, txs) => { + const txsAddresses = [...txs.inputs.map(tx => tx.prev_out.addr), ...txs.out.map(tx => tx.addr)] + const lastAddress = addresses.reverse().find(a => txsAddresses.includes(a.address)) || { + index: 0, + } + return { + index: lastAddress.index, + address: getAddress({ type: 'external', index: lastAddress.index + 1 }).address, + } } const nextPath = (index = 0) => @@ -129,15 +133,16 @@ export async function getAccount({ ), ).then(async results => { const addresses = results.reduce((result, v) => [...result, ...v], []) - const listAddresses = addresses.map(a => a.address) + allAddresses = [...allAddresses, ...listAddresses] + const { txs } = await getTransactions(listAddresses) const hasTransactions = txs.length > 0 - transactions = [...transactions, ...txs.map(computeTransaction(listAddresses))] - lastAddress = hasTransactions ? getLastAddress(addresses, txs[0].out[0]) : lastAddress + transactions = [...transactions, ...txs.map(computeTransaction(allAddresses))] + lastAddress = hasTransactions ? getLastAddress(addresses, txs[0]) : lastAddress if (hasTransactions) { return nextPath(index + (gapLimit - 1)) @@ -154,10 +159,23 @@ export async function getAccount({ currentIndex: lastAddress.index, address: lastAddress.address, } - : {}), + : { + currentIndex: 0, + address: getAddress({ type: 'external', index: 0 }).address, + }), } }) + if (currentIndex > 0) { + for (let i = currentIndex; i--; ) { + allAddresses = [ + ...allAddresses, + getAddress({ type: 'internal', index: i }).address, + getAddress({ type: 'external', index: i }).address, + ] + } + } + return nextPath(currentIndex) } diff --git a/src/i18n/en/translation.yml b/src/i18n/en/translation.yml index 1cf9eb59..d25ad819 100644 --- a/src/i18n/en/translation.yml +++ b/src/i18n/en/translation.yml @@ -9,6 +9,22 @@ language: en: English fr: French +sidebar: + menu: Menu + accounts: Accounts + +dashboard: + title: Dashboard + +send: + title: Send + +receive: + title: Receive + +addAccount: + title: Add account + settings: title: Settings diff --git a/src/i18n/fr/translation.yml b/src/i18n/fr/translation.yml index 08d6d853..23dca7dc 100644 --- a/src/i18n/fr/translation.yml +++ b/src/i18n/fr/translation.yml @@ -9,6 +9,22 @@ language: en: Anglais fr: Français +sidebar: + menu: Menu + accounts: Comptes + +dashboard: + title: Tableau de bord + +send: + title: Envoyer + +receive: + title: Recevoir + +addAccount: + title: Ajouter un compte + settings: title: Réglages diff --git a/src/internals/index.js b/src/internals/index.js index 0a7408f5..2c64c3fc 100644 --- a/src/internals/index.js +++ b/src/internals/index.js @@ -16,12 +16,13 @@ const handlers = Object.keys(func).reduce((result, key) => { return result }, {}) -process.on('message', payload => { +const onMessage = payload => { const { type, data } = payload - const handler = objectPath.get(handlers, type) if (!handler) { return } handler(data) -}) +} + +process.on('message', onMessage) diff --git a/src/internals/usb/devices.js b/src/internals/usb/devices.js index d0a57dfe..abd40bc7 100644 --- a/src/internals/usb/devices.js +++ b/src/internals/usb/devices.js @@ -1,8 +1,6 @@ -// @flow - import CommNodeHid from '@ledgerhq/hw-transport-node-hid' -export default (send: Function) => ({ +export default send => ({ listen: () => { CommNodeHid.listen({ next: e => { diff --git a/src/internals/usb/wallet/accounts.js b/src/internals/usb/wallet/accounts.js index 50c8d84b..b1222ea8 100644 --- a/src/internals/usb/wallet/accounts.js +++ b/src/internals/usb/wallet/accounts.js @@ -122,12 +122,9 @@ export default async ({ const hasTransactions = account.transactions.length > 0 - // If the first account is empty we still add it - if (currentAccount === 0 || hasTransactions) { - accounts[currentAccount] = { - id: xpub58, - ...account, - } + accounts[currentAccount] = { + id: xpub58, + ...account, } if (hasTransactions) { diff --git a/src/main/app.js b/src/main/app.js index 6a809f83..f182d09c 100644 --- a/src/main/app.js +++ b/src/main/app.js @@ -2,8 +2,6 @@ import { app, BrowserWindow } from 'electron' -process.setMaxListeners(100) - // necessary to prevent win from being garbage collected let mainWindow diff --git a/src/main/bridge.js b/src/main/bridge.js index 704ab3b6..f28fcc95 100644 --- a/src/main/bridge.js +++ b/src/main/bridge.js @@ -24,8 +24,7 @@ function onForkChannel(forkType, callType) { } } - compute.send({ type, data }) - compute.on('message', payload => { + const onMessage = payload => { const { type, data, options = {} } = payload if (callType === 'async') { event.sender.send('msg', { type, data }) @@ -36,7 +35,10 @@ function onForkChannel(forkType, callType) { if (options.kill && compute) { kill() } - }) + } + + compute.on('message', onMessage) + compute.send({ type, data }) process.on('exit', kill) } diff --git a/src/main/index.js b/src/main/index.js index 75e8269b..d29f2b74 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,5 +1,7 @@ // @flow +process.setMaxListeners(0) + require('../globals') require('./bridge') require('./app') diff --git a/src/reducers/accounts.js b/src/reducers/accounts.js index 37177266..b3a5b099 100644 --- a/src/reducers/accounts.js +++ b/src/reducers/accounts.js @@ -1,8 +1,11 @@ // @flow import { handleActions } from 'redux-actions' + +import every from 'lodash/every' import get from 'lodash/get' import reduce from 'lodash/reduce' +import uniqBy from 'lodash/uniqBy' import type { State } from 'reducers' import type { Account, Accounts, AccountData } from 'types/common' @@ -12,11 +15,15 @@ export type AccountsState = Accounts const state: AccountsState = {} function getAccount(account: Account) { + const transactions = get(account.data, 'transactions', []) + + transactions.sort((a, b) => b.time - a.time) + return { ...account, data: { - ...account.data, - transactions: get(account.data, 'transactions', []).sort((a, b) => b.time - a.time), + ...(account.data || {}), + transactions, }, } } @@ -34,16 +41,21 @@ const handlers: Object = { const account = state[accountID] const { data: accountData } = account - const balance = get(accountData, 'balance', 0) - const transactions = get(accountData, 'transactions', []) + const transactions = uniqBy( + [...get(accountData, 'transactions', []), ...data.transactions], + tx => tx.hash, + ) const currentIndex = data.currentIndex ? data.currentIndex : get(accountData, 'currentIndex', 0) account.data = { ...accountData, ...data, - balance: balance + data.balance, + balance: transactions.reduce((result, v) => { + result += v.balance + return result + }, 0), currentIndex, - transactions: [...transactions, ...data.transactions], + transactions, } return { @@ -81,4 +93,8 @@ export function getAccountData(state: State, id: string): AccountData | null { return get(getAccountById(state, id), 'data', null) } +export function canCreateAccount(state: State): boolean { + return every(getAccounts(state), a => a.data.transactions.length > 0) +} + export default handleActions(handlers, state) diff --git a/src/reducers/settings.js b/src/reducers/settings.js index 3e4eaa5c..daceacdc 100644 --- a/src/reducers/settings.js +++ b/src/reducers/settings.js @@ -8,7 +8,12 @@ import type { Settings } from 'types/common' export type SettingsState = Object -const state: SettingsState = {} +const state: SettingsState = { + language: 'en', + password: { + state: false, + }, +} const handlers: Object = { SAVE_SETTINGS: (state: SettingsState, { payload: settings }: { payload: Settings }) => ({ diff --git a/src/renderer/events.js b/src/renderer/events.js index 97a55617..d2aa4baa 100644 --- a/src/renderer/events.js +++ b/src/renderer/events.js @@ -6,6 +6,8 @@ import get from 'lodash/get' import type { Accounts } from 'types/common' +import { CHECK_UPDATE_TIMEOUT, SYNC_ACCOUNT_TIMEOUT } from 'constants' + import { updateDevices, addDevice, removeDevice } from 'actions/devices' import { syncAccount } from 'actions/accounts' import { setUpdateStatus } from 'reducers/update' @@ -16,10 +18,6 @@ type MsgPayload = { data: any, } -// wait a bit before launching update check -const CHECK_UPDATE_TIMEOUT = 3e3 -const SYNC_ACCOUNT_TIMEOUT = 5e3 - let syncAccounts = true let syncTimeout @@ -39,11 +37,15 @@ export function sendSyncEvent(channel: string, msgType: string, data: any): any export function startSyncAccounts(accounts: Accounts) { syncAccounts = true + sendEvent('accounts', 'sync.all', { - accounts: Object.entries(accounts).map(([id, account]: [string, any]) => ({ - id, - currentIndex: get(account, 'data.currentIndex', 0), - })), + accounts: Object.entries(accounts).map(([id, account]: [string, any]) => { + const currentIndex = get(account, 'data.currentIndex', 0) + return { + id, + currentIndex, + } + }), }) } @@ -52,13 +54,19 @@ export function stopSyncAccounts() { clearTimeout(syncTimeout) } +export function checkUpdates() { + setTimeout(() => sendEvent('msg', 'updater.init'), CHECK_UPDATE_TIMEOUT) +} + export default ({ store, locked }: { store: Object, locked: boolean }) => { const handlers = { accounts: { sync: { success: accounts => { if (syncAccounts) { - accounts.forEach(account => store.dispatch(syncAccount(account))) + accounts.forEach( + account => account.transactions.length > 0 && store.dispatch(syncAccount(account)), + ) syncTimeout = setTimeout(() => { const newAccounts = getAccounts(store.getState()) startSyncAccounts(newAccounts) @@ -107,6 +115,6 @@ export default ({ store, locked }: { store: Object, locked: boolean }) => { if (__PROD__) { // Start check of eventual updates - setTimeout(() => sendEvent('msg', 'updater.init'), CHECK_UPDATE_TIMEOUT) + checkUpdates() } } diff --git a/yarn.lock b/yarn.lock index 56e4af44..8a86f52a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -93,31 +93,30 @@ redux "^3.7.2" redux-thunk "^2.2.0" -"@ledgerhq/hw-app-btc@^2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-2.0.5.tgz#44dabd18c4dcc68127869d384b06f0601c4a7a0e" +"@ledgerhq/hw-app-btc@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-2.1.0.tgz#6f7354ac4838eda4d78252b4fe984cd034a317bf" dependencies: - "@ledgerhq/hw-transport" "^2.0.5" + "@ledgerhq/hw-transport" "^2.1.0" -"@ledgerhq/hw-app-eth@^2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-2.0.5.tgz#844d938d7985f498058e7bd5cd48bc86b510d5ec" +"@ledgerhq/hw-app-eth@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-2.1.0.tgz#66dfbe4b11be9e22ab5574db603cd70aa9b82bf0" dependencies: - "@ledgerhq/hw-transport" "^2.0.5" + "@ledgerhq/hw-transport" "^2.1.0" -"@ledgerhq/hw-transport-node-hid@^2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-2.0.6.tgz#29e76b05156218ccd1fe4c78c887829ac9598f98" +"@ledgerhq/hw-transport-node-hid@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-2.1.0.tgz#bcaeab27feb7d869f8a8d96cee1e4934f3c87040" dependencies: - "@ledgerhq/hw-transport" "^2.0.5" + "@ledgerhq/hw-transport" "^2.1.0" node-hid "^0.7.2" -"@ledgerhq/hw-transport@^2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-2.0.5.tgz#5070a0e8dfb22f365b08dcf10fb03a8bf44fa5bf" +"@ledgerhq/hw-transport@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-2.1.0.tgz#7d8460a2ea8d5344796482458b6adb11c1cfc706" dependencies: events "^1.1.1" - invariant "^2.2.0" "@storybook/addon-actions@^3.3.10": version "3.3.10" @@ -2411,9 +2410,9 @@ color@^0.11.0: color-convert "^1.3.0" color-string "^0.3.0" -color@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" +color@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" dependencies: color-convert "^1.9.1" color-string "^1.5.2" @@ -3570,9 +3569,9 @@ eslint-module-utils@^2.1.1: debug "^2.6.8" pkg-dir "^1.0.0" -eslint-plugin-flowtype@^2.41.1: - version "2.41.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.41.1.tgz#0996e1ea1d501dfc945802453a304ae9e8098b78" +eslint-plugin-flowtype@^2.42.0: + version "2.42.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.42.0.tgz#7fcc98df4ed9482a22ac10ba4ca48d649c4c733a" dependencies: lodash "^4.15.0" @@ -4063,9 +4062,9 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -flow-bin@^0.63.1: - version "0.63.1" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.63.1.tgz#ab00067c197169a5fb5b4996c8f6927b06694828" +flow-bin@^0.64.0: + version "0.64.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.64.0.tgz#ddd3fb3b183ab1ab35a5d5dec9caf5ebbcded167" flow-typed@^2.2.3: version "2.2.3" @@ -7323,9 +7322,9 @@ react-html-attributes@^1.3.0: dependencies: html-element-attributes "^1.0.0" -react-i18next@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-7.3.1.tgz#b0ca03db9cc4d4067b6481d09d902a5166d620a0" +react-i18next@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-7.3.2.tgz#5036dc0371808bd8afe0c9a4a738ebd39721e33b" dependencies: hoist-non-react-statics "2.3.1" html-parse-stringify2 "2.0.1"