Browse Source

Use Operation term instead of Transaction

master
meriadec 7 years ago
parent
commit
26f549e06d
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 6
      src/components/AccountPage/index.js
  2. 30
      src/components/DashboardPage/index.js
  3. 2
      src/components/OperationsList/ConfirmationCheck.js
  4. 46
      src/components/OperationsList/index.js
  5. 21
      src/components/OperationsList/stories.js
  6. 2
      src/components/SelectAccount/stories.js
  7. 5
      src/components/base/FormattedVal/index.js
  8. 6
      src/components/modals/AddAccount/ImportAccounts.js
  9. 6
      src/components/modals/AddAccount/index.js
  10. 8
      src/components/modals/SettingsAccount.js
  11. 2
      src/helpers/__tests__/balance.test.js
  12. 47
      src/helpers/btc.js
  13. 4
      src/internals/accounts/sync.js
  14. 8
      src/internals/usb/wallet/accounts.js
  15. 18
      src/reducers/accounts.js
  16. 10
      src/renderer/events.js
  17. 2
      src/renderer/i18n/instanciate.js
  18. 2
      src/renderer/i18n/storybook.js
  19. 11
      src/types/common.js
  20. 0
      static/i18n/en/operationsList.yml
  21. 0
      static/i18n/fr/operationsList.yml

6
src/components/AccountPage/index.js

@ -28,7 +28,7 @@ import Box from 'components/base/Box'
import Button from 'components/base/Button' import Button from 'components/base/Button'
import FormattedVal from 'components/base/FormattedVal' import FormattedVal from 'components/base/FormattedVal'
import PillsDaysCount from 'components/PillsDaysCount' import PillsDaysCount from 'components/PillsDaysCount'
import TransactionsList from 'components/TransactionsList' import OperationsList from 'components/OperationsList'
import AccountHeader from './AccountHeader' import AccountHeader from './AccountHeader'
@ -156,9 +156,9 @@ class AccountPage extends PureComponent<Props, State> {
)} )}
/> />
</Box> </Box>
<TransactionsList <OperationsList
title={t('account:lastOperations')} title={t('account:lastOperations')}
transactions={account.transactions} operations={account.operations}
minConfirmations={account.settings.minConfirmations} minConfirmations={account.settings.minConfirmations}
/> />
</Box> </Box>

30
src/components/DashboardPage/index.js

@ -10,7 +10,7 @@ import chunk from 'lodash/chunk'
import get from 'lodash/get' import get from 'lodash/get'
import sortBy from 'lodash/sortBy' import sortBy from 'lodash/sortBy'
import type { Account, Accounts, T } from 'types/common' import type { Account, Accounts, Operations, T } from 'types/common'
import { getVisibleAccounts } from 'reducers/accounts' import { getVisibleAccounts } from 'reducers/accounts'
import { getCounterValue } from 'reducers/settings' import { getCounterValue } from 'reducers/settings'
@ -23,7 +23,7 @@ import BalanceSummary from 'components/BalanceSummary'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import PillsDaysCount from 'components/PillsDaysCount' import PillsDaysCount from 'components/PillsDaysCount'
import Text from 'components/base/Text' import Text from 'components/base/Text'
import TransactionsList from 'components/TransactionsList' import OperationsList from 'components/OperationsList'
import AccountCard from './AccountCard' import AccountCard from './AccountCard'
import AccountsOrder from './AccountsOrder' import AccountsOrder from './AccountsOrder'
@ -48,21 +48,21 @@ type Props = {
type State = { type State = {
accountsChunk: Array<Array<Account | null>>, accountsChunk: Array<Array<Account | null>>,
allTransactions: Array<Object>, allOperations: Operations,
selectedTime: string, selectedTime: string,
daysCount: number, daysCount: number,
} }
const ACCOUNTS_BY_LINE = 3 const ACCOUNTS_BY_LINE = 3
const ALL_TRANSACTIONS_LIMIT = 10 const ALL_OPERATIONS_LIMIT = 10
const getAllTransactions = accounts => { const getAllOperations = accounts => {
const allTransactions = accounts.reduce((result, account) => { const allOperations = accounts.reduce((result, account) => {
const transactions = get(account, 'transactions', []) const operations = get(account, 'operations', [])
result = [ result = [
...result, ...result,
...transactions.map(t => ({ ...operations.map(t => ({
...t, ...t,
account, account,
})), })),
@ -71,9 +71,9 @@ const getAllTransactions = accounts => {
return result return result
}, []) }, [])
return sortBy(allTransactions, t => t.receivedAt) return sortBy(allOperations, t => t.receivedAt)
.reverse() .reverse()
.slice(0, ALL_TRANSACTIONS_LIMIT) .slice(0, ALL_OPERATIONS_LIMIT)
} }
const getAccountsChunk = accounts => { const getAccountsChunk = accounts => {
@ -88,7 +88,7 @@ const getAccountsChunk = accounts => {
class DashboardPage extends PureComponent<Props, State> { class DashboardPage extends PureComponent<Props, State> {
state = { state = {
accountsChunk: getAccountsChunk(this.props.accounts), accountsChunk: getAccountsChunk(this.props.accounts),
allTransactions: getAllTransactions(this.props.accounts), allOperations: getAllOperations(this.props.accounts),
selectedTime: 'week', selectedTime: 'week',
daysCount: 7, daysCount: 7,
} }
@ -97,7 +97,7 @@ class DashboardPage extends PureComponent<Props, State> {
if (nextProps.accounts !== this.props.accounts) { if (nextProps.accounts !== this.props.accounts) {
this.setState({ this.setState({
accountsChunk: getAccountsChunk(nextProps.accounts), accountsChunk: getAccountsChunk(nextProps.accounts),
allTransactions: getAllTransactions(nextProps.accounts), allOperations: getAllOperations(nextProps.accounts),
}) })
} }
} }
@ -110,7 +110,7 @@ class DashboardPage extends PureComponent<Props, State> {
render() { render() {
const { push, accounts, t, counterValue } = this.props const { push, accounts, t, counterValue } = this.props
const { accountsChunk, allTransactions, selectedTime, daysCount } = this.state const { accountsChunk, allOperations, selectedTime, daysCount } = this.state
const totalAccounts = accounts.length const totalAccounts = accounts.length
@ -189,11 +189,11 @@ class DashboardPage extends PureComponent<Props, State> {
))} ))}
</Box> </Box>
</Box> </Box>
<TransactionsList <OperationsList
canShowMore canShowMore
title={t('dashboard:recentActivity')} title={t('dashboard:recentActivity')}
withAccounts withAccounts
transactions={allTransactions} operations={allOperations}
onAccountClick={account => push(`/account/${account.id}`)} onAccountClick={account => push(`/account/${account.id}`)}
/> />
</Fragment> </Fragment>

2
src/components/TransactionsList/ConfirmationCheck.js → src/components/OperationsList/ConfirmationCheck.js

@ -36,7 +36,7 @@ const ConfirmationCheck = ({
return ( return (
<Tooltip <Tooltip
render={() => render={() =>
isConfirmed ? t('transactionsList:confirmed') : t('transactionsList:notConfirmed') isConfirmed ? t('operationsList:confirmed') : t('operationsList:notConfirmed')
} }
> >
<Container isConfirmed={isConfirmed}> <Container isConfirmed={isConfirmed}>

46
src/components/TransactionsList/index.js → src/components/OperationsList/index.js

@ -9,7 +9,7 @@ import noop from 'lodash/noop'
import isEqual from 'lodash/isEqual' import isEqual from 'lodash/isEqual'
import { getIconByCoinType } from '@ledgerhq/currencies/react' import { getIconByCoinType } from '@ledgerhq/currencies/react'
import type { Transaction as TransactionType, T } from 'types/common' import type { Operation as OperationType, T } from 'types/common'
import IconAngleDown from 'icons/AngleDown' import IconAngleDown from 'icons/AngleDown'
import Box, { Card } from 'components/base/Box' import Box, { Card } from 'components/base/Box'
@ -55,7 +55,7 @@ HeaderCol.defaultProps = {
children: undefined, children: undefined,
} }
const TransactionRaw = styled(Box).attrs({ const OperationRaw = styled(Box).attrs({
horizontal: true, horizontal: true,
alignItems: 'center', alignItems: 'center',
})` })`
@ -97,7 +97,7 @@ const ShowMore = styled(Box).attrs({
} }
` `
const Transaction = ({ const Operation = ({
t, t,
onAccountClick, onAccountClick,
tx, tx,
@ -106,14 +106,14 @@ const Transaction = ({
}: { }: {
t: T, t: T,
onAccountClick?: Function, onAccountClick?: Function,
tx: TransactionType, tx: OperationType,
withAccounts?: boolean, withAccounts?: boolean,
minConfirmations: number, minConfirmations: number,
}) => { }) => {
const time = moment(tx.receivedAt) const time = moment(tx.receivedAt)
const Icon = getIconByCoinType(get(tx, 'account.currency.coinType')) const Icon = getIconByCoinType(get(tx, 'account.currency.coinType'))
return ( return (
<TransactionRaw> <OperationRaw>
<Cell size={DATE_COL_SIZE} justifyContent="space-between"> <Cell size={DATE_COL_SIZE} justifyContent="space-between">
<Box> <Box>
<Day>{time.format('DD MMM')}</Day> <Day>{time.format('DD MMM')}</Day>
@ -149,7 +149,7 @@ const Transaction = ({
}} }}
> >
<Box ff="Open Sans" fontSize={3} color="graphite"> <Box ff="Open Sans" fontSize={3} color="graphite">
{tx.balance > 0 ? t('transactionsList:from') : t('transactionsList:to')} {tx.amount > 0 ? t('operationsList:from') : t('operationsList:to')}
</Box> </Box>
<Box <Box
color="dark" color="dark"
@ -167,7 +167,7 @@ const Transaction = ({
</Cell> </Cell>
<Cell size={AMOUNT_COL_SIZE} justifyContent="flex-end"> <Cell size={AMOUNT_COL_SIZE} justifyContent="flex-end">
<FormattedVal <FormattedVal
val={tx.balance} val={tx.amount}
unit={get(tx, 'account.unit')} unit={get(tx, 'account.unit')}
showCode showCode
fontSize={4} fontSize={4}
@ -181,11 +181,11 @@ const Transaction = ({
t={t} t={t}
/> />
</Cell> </Cell>
</TransactionRaw> </OperationRaw>
) )
} }
Transaction.defaultProps = { Operation.defaultProps = {
onAccountClick: noop, onAccountClick: noop,
withAccounts: false, withAccounts: false,
} }
@ -193,14 +193,14 @@ Transaction.defaultProps = {
type Props = { type Props = {
t: T, t: T,
onAccountClick?: Function, onAccountClick?: Function,
transactions: Array<TransactionType>, operations: Array<OperationType>,
withAccounts?: boolean, withAccounts?: boolean,
minConfirmations: number, minConfirmations: number,
title?: string, title?: string,
canShowMore: boolean, canShowMore: boolean,
} }
class TransactionsList extends Component<Props> { class OperationsList extends Component<Props> {
static defaultProps = { static defaultProps = {
onAccountClick: noop, onAccountClick: noop,
withAccounts: false, withAccounts: false,
@ -221,16 +221,16 @@ class TransactionsList extends Component<Props> {
return true return true
} }
return !isEqual(this._hashCache, this.getHashCache(nextProps.transactions)) return !isEqual(this._hashCache, this.getHashCache(nextProps.operations))
} }
getHashCache = (transactions: Array<TransactionType>) => transactions.map(t => t.hash) getHashCache = (operations: Array<OperationType>) => operations.map(t => t.hash)
_hashCache = null _hashCache = null
render() { render() {
const { const {
transactions, operations,
title, title,
withAccounts, withAccounts,
onAccountClick, onAccountClick,
@ -239,26 +239,26 @@ class TransactionsList extends Component<Props> {
t, t,
} = this.props } = this.props
this._hashCache = this.getHashCache(transactions) this._hashCache = this.getHashCache(operations)
return ( return (
<Defer> <Defer>
<Card flow={1} title={title} p={0}> <Card flow={1} title={title} p={0}>
<Box horizontal pt={4}> <Box horizontal pt={4}>
<HeaderCol size={DATE_COL_SIZE}>{t('transactionsList:date')}</HeaderCol> <HeaderCol size={DATE_COL_SIZE}>{t('operationsList:date')}</HeaderCol>
{withAccounts && ( {withAccounts && (
<HeaderCol size={ACCOUNT_COL_SIZE}>{t('transactionsList:account')}</HeaderCol> <HeaderCol size={ACCOUNT_COL_SIZE}>{t('operationsList:account')}</HeaderCol>
)} )}
<HeaderCol grow>{t('transactionsList:address')}</HeaderCol> <HeaderCol grow>{t('operationsList:address')}</HeaderCol>
<HeaderCol size={AMOUNT_COL_SIZE} justifyContent="flex-end"> <HeaderCol size={AMOUNT_COL_SIZE} justifyContent="flex-end">
{t('transactionsList:amount')} {t('operationsList:amount')}
</HeaderCol> </HeaderCol>
<HeaderCol size={CONFIRMATION_COL_SIZE} px={0} /> <HeaderCol size={CONFIRMATION_COL_SIZE} px={0} />
</Box> </Box>
<Box> <Box>
{transactions.map(trans => ( {operations.map(trans => (
<Transaction <Operation
t={t} t={t}
key={`{${trans.hash}-${trans.account ? trans.account.id : ''}`} key={`{${trans.hash}-${trans.account ? trans.account.id : ''}`}
withAccounts={withAccounts} withAccounts={withAccounts}
@ -271,7 +271,7 @@ class TransactionsList extends Component<Props> {
{canShowMore && ( {canShowMore && (
<ShowMore> <ShowMore>
<span>{t('transactionsList:showMore')}</span> <span>{t('operationsList:showMore')}</span>
<IconAngleDown width={8} height={8} /> <IconAngleDown width={8} height={8} />
</ShowMore> </ShowMore>
)} )}
@ -281,4 +281,4 @@ class TransactionsList extends Component<Props> {
} }
} }
export default translate()(TransactionsList) export default translate()(OperationsList)

21
src/components/TransactionsList/stories.js → src/components/OperationsList/stories.js

@ -1,28 +1,37 @@
// @flow // @flow
import React from 'react' import React from 'react'
import { getDefaultUnitByCoinType } from '@ledgerhq/currencies'
import { storiesOf } from '@storybook/react' import { storiesOf } from '@storybook/react'
import { boolean } from '@storybook/addon-knobs' import { boolean } from '@storybook/addon-knobs'
import TransactionsList from 'components/TransactionsList' import OperationsList from 'components/OperationsList'
const stories = storiesOf('Components', module) const stories = storiesOf('Components', module)
const transactions = [ const unit = getDefaultUnitByCoinType(0)
const operations = [
{ {
address: '5c6ea1716520c7d6e038d36a3223faced3c', address: '5c6ea1716520c7d6e038d36a3223faced3c',
hash: '5c6ea1716520c7d6e038d36a3223faced3c4b8f7ffb69d9fb5bd527d562fdb62', hash: '5c6ea1716520c7d6e038d36a3223faced3c4b8f7ffb69d9fb5bd527d562fdb62',
balance: 130000000, amount: 130000000,
receivedAt: '2018-01-09T16:03:52Z', receivedAt: '2018-01-09T16:03:52Z',
account: {
unit,
},
}, },
{ {
address: '27416a48caab90fab053b507b8b6b9d4', address: '27416a48caab90fab053b507b8b6b9d4',
hash: '27416a48caab90fab053b507b8b6b9d48fba75421d3bfdbae4b85f64024bc9c4', hash: '27416a48caab90fab053b507b8b6b9d48fba75421d3bfdbae4b85f64024bc9c4',
balance: 65000000, amount: -65000000,
receivedAt: '2018-01-09T16:02:40Z', receivedAt: '2018-01-09T16:02:40Z',
account: {
unit,
},
}, },
] ]
stories.add('TransactionsList', () => ( stories.add('OperationsList', () => (
<TransactionsList transactions={transactions} canShowMore={boolean('canShowMore')} /> <OperationsList operations={operations} canShowMore={boolean('canShowMore')} />
)) ))

2
src/components/SelectAccount/stories.js

@ -22,7 +22,7 @@ export const accounts = [...Array(20)].map(() => ({
name: chance.name(), name: chance.name(),
path: '', path: '',
rootPath: '', rootPath: '',
transactions: [], operations: [],
unit: getDefaultUnitByCoinType(1), unit: getDefaultUnitByCoinType(1),
settings: { settings: {
minConfirmations: 2, minConfirmations: 2,

5
src/components/base/FormattedVal/index.js

@ -2,6 +2,7 @@
import React from 'react' import React from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import isUndefined from 'lodash/isUndefined'
import type { Unit } from '@ledgerhq/currencies' import type { Unit } from '@ledgerhq/currencies'
@ -27,6 +28,10 @@ function FormattedVal(props: Props) {
const { fiat, isPercent, alwaysShowSign, showCode, ...p } = props const { fiat, isPercent, alwaysShowSign, showCode, ...p } = props
let { val, unit } = props let { val, unit } = props
if (isUndefined(val)) {
throw new Error('FormattedVal require a `val` prop. Received `undefined`')
}
const isNegative = val < 0 const isNegative = val < 0
let text = '' let text = ''

6
src/components/modals/AddAccount/ImportAccounts.js

@ -3,7 +3,7 @@
import React, { PureComponent } 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, Accounts } from 'types/common'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import Button from 'components/base/Button' import Button from 'components/base/Button'
@ -13,7 +13,7 @@ import Input from 'components/base/Input'
type Props = { type Props = {
t: T, t: T,
accounts: Array<Object>, accounts: Accounts,
onImportAccounts: Function, onImportAccounts: Function,
} }
@ -110,7 +110,7 @@ class ImportAccounts extends PureComponent<Props, State> {
val={account.balance} val={account.balance}
/> />
</Box> </Box>
<Box>Transactions: {account.transactions.length}</Box> <Box>Operations: {account.operations.length}</Box>
</Box> </Box>
</Box> </Box>
) )

6
src/components/modals/AddAccount/index.js

@ -88,7 +88,7 @@ const Steps = {
val={progress.balance || 0} val={progress.balance || 0}
/> />
</Box> </Box>
<Box>Transactions: {progress.transactions || 0}</Box> <Box>Operations: {progress.operations || 0}</Box>
{progress.success && <Box>Finish ! Next account in progress...</Box>} {progress.success && <Box>Finish ! Next account in progress...</Box>}
</Box> </Box>
)} )}
@ -96,8 +96,8 @@ const Steps = {
), ),
listAccounts: (props: Object) => { listAccounts: (props: Object) => {
const { accounts, archivedAccounts } = props const { accounts, archivedAccounts } = props
const emptyAccounts = accounts.filter(account => account.transactions.length === 0) const emptyAccounts = accounts.filter(account => account.operations.length === 0)
const existingAccounts = accounts.filter(account => account.transactions.length > 0) const existingAccounts = accounts.filter(account => account.operations.length > 0)
const canCreateAccount = props.canCreateAccount && emptyAccounts.length === 1 const canCreateAccount = props.canCreateAccount && emptyAccounts.length === 1
const newAccount = emptyAccounts[0] const newAccount = emptyAccounts[0]
return ( return (

8
src/components/modals/SettingsAccount.js

@ -50,8 +50,8 @@ const defaultState = {
nameHovered: false, nameHovered: false,
} }
function hasNoTransactions(account: Account) { function hasNoOperations(account: Account) {
return get(account, 'transactions.length', 0) === 0 return get(account, 'operations.length', 0) === 0
} }
class SettingsAccount extends PureComponent<Props, State> { class SettingsAccount extends PureComponent<Props, State> {
@ -133,7 +133,7 @@ class SettingsAccount extends PureComponent<Props, State> {
handleArchiveAccount = (account: Account) => () => { handleArchiveAccount = (account: Account) => () => {
const { push, closeModal, updateAccount, removeAccount } = this.props const { push, closeModal, updateAccount, removeAccount } = this.props
const shouldRemove = hasNoTransactions(account) const shouldRemove = hasNoOperations(account)
if (shouldRemove) { if (shouldRemove) {
removeAccount(account) removeAccount(account)
@ -212,7 +212,7 @@ class SettingsAccount extends PureComponent<Props, State> {
</ModalContent> </ModalContent>
<ModalFooter horizontal justify="flex-end" flow={2}> <ModalFooter horizontal justify="flex-end" flow={2}>
<Button onClick={this.handleArchiveAccount(account)}> <Button onClick={this.handleArchiveAccount(account)}>
{hasNoTransactions(account) ? 'Remove account' : 'Archive account'} {hasNoOperations(account) ? 'Remove account' : 'Archive account'}
</Button> </Button>
<Button primary>Go to account</Button> <Button primary>Go to account</Button>
</ModalFooter> </ModalFooter>

2
src/helpers/__tests__/balance.test.js

@ -69,7 +69,7 @@ describe('helpers > balance', () => {
]) ])
}) })
test('should work if interval dont contain transactions', () => { test('should work if interval dont contain operations', () => {
const account = { const account = {
coinType: 0, coinType: 0,
balanceByDay: { balanceByDay: {

47
src/helpers/btc.js

@ -7,7 +7,7 @@ import groupBy from 'lodash/groupBy'
import noop from 'lodash/noop' import noop from 'lodash/noop'
import uniqBy from 'lodash/uniqBy' import uniqBy from 'lodash/uniqBy'
import type { Transactions } from 'types/common' import type { Operations } from 'types/common'
const GAP_LIMIT_ADDRESSES = 20 const GAP_LIMIT_ADDRESSES = 20
@ -22,7 +22,7 @@ export const networks = [
}, },
] ]
export function computeTransaction(addresses: Array<string>) { export function computeOperation(addresses: Array<string>) {
return (t: Object) => { return (t: Object) => {
const outputVal = t.outputs const outputVal = t.outputs
.filter(o => addresses.includes(o.address)) .filter(o => addresses.includes(o.address))
@ -30,10 +30,11 @@ export function computeTransaction(addresses: Array<string>) {
const inputVal = t.inputs const inputVal = t.inputs
.filter(i => addresses.includes(i.address)) .filter(i => addresses.includes(i.address))
.reduce((acc, cur) => acc + cur.value, 0) .reduce((acc, cur) => acc + cur.value, 0)
const balance = outputVal - inputVal const amount = outputVal - inputVal
return { return {
address: t.balance > 0 ? t.inputs[0].address : t.outputs[0].address, id: t.hash,
balance, address: t.amount > 0 ? t.inputs[0].address : t.outputs[0].address,
amount,
confirmations: t.confirmations, confirmations: t.confirmations,
hash: t.hash, hash: t.hash,
receivedAt: t.received_at, receivedAt: t.received_at,
@ -41,8 +42,8 @@ export function computeTransaction(addresses: Array<string>) {
} }
} }
export function getBalanceByDay(transactions: Transactions) { export function getBalanceByDay(operations: Operations) {
const txsByDate = groupBy(transactions, tx => { const txsByDate = groupBy(operations, tx => {
const [date] = new Date(tx.receivedAt).toISOString().split('T') const [date] = new Date(tx.receivedAt).toISOString().split('T')
return date return date
}) })
@ -55,7 +56,7 @@ export function getBalanceByDay(transactions: Transactions) {
const txs = txsByDate[k] const txs = txsByDate[k]
balance += txs.reduce((r, v) => { balance += txs.reduce((r, v) => {
r += v.balance r += v.amount
return r return r
}, 0) }, 0)
@ -91,7 +92,7 @@ export async function getAccount({
const script = segwit ? parseInt(network.scriptHash, 10) : parseInt(network.pubKeyHash, 10) const script = segwit ? parseInt(network.scriptHash, 10) : parseInt(network.pubKeyHash, 10)
let balance = 0 let balance = 0
let transactions = [] let operations = []
let lastAddress = null let lastAddress = null
const pubKeyToSegwitAddress = (pubKey, scriptVersion) => { const pubKeyToSegwitAddress = (pubKey, scriptVersion) => {
@ -149,31 +150,31 @@ export async function getAccount({
let txs = [] let txs = []
const transactionsOpts = { coin_type: coinType } const operationsOpts = { coin_type: coinType }
try { try {
txs = await ledger.getTransactions(listAddresses, transactionsOpts) txs = await ledger.getTransactions(listAddresses, operationsOpts)
txs = txs.filter(t => !allTxsHash.includes(t.hash)).reverse() txs = txs.filter(t => !allTxsHash.includes(t.hash)).reverse()
} catch (e) { } catch (e) {
console.log('getTransactions', e) // eslint-disable-line no-console console.log('getOperations', e) // eslint-disable-line no-console
} }
const hasTransactions = txs.length > 0 const hasOperations = txs.length > 0
if (hasTransactions) { if (hasOperations) {
const newTransactions = txs.map(computeTransaction(allAddresses)) const newOperations = txs.map(computeOperation(allAddresses))
const txHashs = transactions.map(t => t.hash) const txHashs = operations.map(t => t.hash)
balance = newTransactions balance = newOperations
.filter(t => !txHashs.includes(t.hash)) .filter(t => !txHashs.includes(t.hash))
.reduce((result, v) => result + v.balance, balance) .reduce((result, v) => result + v.amount, balance)
lastAddress = getLastAddress(addresses, txs[0]) lastAddress = getLastAddress(addresses, txs[0])
transactions = uniqBy([...transactions, ...newTransactions], t => t.hash) operations = uniqBy([...operations, ...newOperations], t => t.hash)
onProgress({ onProgress({
balance, balance,
transactions: transactions.length, operations: operations.length,
}) })
return nextPath(index + (GAP_LIMIT_ADDRESSES - 1)) return nextPath(index + (GAP_LIMIT_ADDRESSES - 1))
@ -189,11 +190,11 @@ export async function getAccount({
return { return {
...nextAddress, ...nextAddress,
addresses: transactions.length > 0 ? allAddresses : [], addresses: operations.length > 0 ? allAddresses : [],
balance, balance,
balanceByDay: getBalanceByDay(transactions), balanceByDay: getBalanceByDay(operations),
rootPath, rootPath,
transactions, operations,
} }
}) })

4
src/internals/accounts/sync.js

@ -4,9 +4,9 @@ import { getAccount, getHDNode, networks } from 'helpers/btc'
const network = networks[1] const network = networks[1]
function syncAccount({ id, transactions, ...currentAccount }) { function syncAccount({ id, operations, ...currentAccount }) {
const hdnode = getHDNode({ xpub58: id, network }) const hdnode = getHDNode({ xpub58: id, network })
const allTxsHash = transactions.map(t => t.hash) const allTxsHash = operations.map(t => t.hash)
return getAccount({ hdnode, network, allTxsHash, segwit: true, ...currentAccount }).then( return getAccount({ hdnode, network, allTxsHash, segwit: true, ...currentAccount }).then(
account => ({ account => ({
id, id,

8
src/internals/usb/wallet/accounts.js

@ -154,11 +154,11 @@ export default async ({
network, network,
rootPath: path, rootPath: path,
segwit, segwit,
onProgress: ({ transactions, ...progress }) => onProgress: ({ operations, ...progress }) =>
transactions > 0 && onProgress({ account: currentAccount, transactions, ...progress }), operations > 0 && onProgress({ account: currentAccount, operations, ...progress }),
}) })
const hasTransactions = account.transactions.length > 0 const hasOperations = account.operations.length > 0
accounts.push({ accounts.push({
id: xpub58, id: xpub58,
@ -166,7 +166,7 @@ export default async ({
...account, ...account,
}) })
if (hasTransactions) { if (hasOperations) {
onProgress({ onProgress({
success: true, success: true,
}) })

18
src/reducers/accounts.js

@ -16,12 +16,12 @@ export type AccountsState = Accounts
const state: AccountsState = [] const state: AccountsState = []
function orderAccountsTransactions(account: Account) { function orderAccountsOperations(account: Account) {
const { transactions } = account const { operations } = account
transactions.sort((a, b) => new Date(b.receivedAt) - new Date(a.receivedAt)) operations.sort((a, b) => new Date(b.receivedAt) - new Date(a.receivedAt))
return { return {
...account, ...account,
transactions, operations,
} }
} }
@ -42,7 +42,7 @@ const handlers: Object = {
ADD_ACCOUNT: ( ADD_ACCOUNT: (
state: AccountsState, state: AccountsState,
{ payload: account }: { payload: Account }, { payload: account }: { payload: Account },
): AccountsState => [...state, orderAccountsTransactions(account)], ): AccountsState => [...state, orderAccountsOperations(account)],
UPDATE_ACCOUNT: ( UPDATE_ACCOUNT: (
state: AccountsState, state: AccountsState,
@ -58,7 +58,7 @@ const handlers: Object = {
...account, ...account,
} }
return orderAccountsTransactions(updatedAccount) return orderAccountsOperations(updatedAccount)
}), }),
REMOVE_ACCOUNT: (state: AccountsState, { payload: account }: { payload: Account }) => REMOVE_ACCOUNT: (state: AccountsState, { payload: account }: { payload: Account }) =>
@ -96,7 +96,7 @@ export function getAccountById(state: { accounts: AccountsState }, id: string):
} }
export function canCreateAccount(state: State): boolean { export function canCreateAccount(state: State): boolean {
return every(getAccounts(state), a => get(a, 'transactions.length', 0) > 0) return every(getAccounts(state), a => get(a, 'operations.length', 0) > 0)
} }
export function serializeAccounts(accounts: Array<Object>) { export function serializeAccounts(accounts: Array<Object>) {
@ -119,7 +119,7 @@ export function serializeAccounts(accounts: Array<Object>) {
return { return {
...a, ...a,
transactions: account.transactions.map(t => ({ operations: account.operations.map(t => ({
...t, ...t,
account: a, account: a,
})), })),
@ -139,7 +139,7 @@ export function deserializeAccounts(accounts: Accounts) {
name: account.name, name: account.name,
path: account.path, path: account.path,
rootPath: account.rootPath, rootPath: account.rootPath,
transactions: account.transactions.map(({ account, ...t }) => t), operations: account.operations.map(({ account, ...t }) => t),
unit: account.unit, unit: account.unit,
settings: account.settings, settings: account.settings,
})) }))

10
src/renderer/events.js

@ -57,14 +57,14 @@ export function startSyncAccounts(accounts: Accounts) {
syncAccountsInProgress = true syncAccountsInProgress = true
sendEvent('accounts', 'sync.all', { sendEvent('accounts', 'sync.all', {
accounts: accounts.map(account => { accounts: accounts.map(account => {
const { id, coinType, rootPath, addresses, index, transactions } = account const { id, coinType, rootPath, addresses, index, operations } = account
return { return {
id, id,
coinType, coinType,
allAddresses: addresses, allAddresses: addresses,
currentIndex: index, currentIndex: index,
rootPath, rootPath,
transactions, operations,
} }
}), }),
}) })
@ -114,9 +114,9 @@ export default ({ store, locked }: { store: Object, locked: boolean }) => {
return return
} }
const { name, balance, balanceByDay, transactions } = existingAccount const { name, balance, balanceByDay, operations } = existingAccount
if (account.transactions.length > 0) { if (account.operations.length > 0) {
d.sync(`Update account - ${name}`) d.sync(`Update account - ${name}`)
const updatedAccount = { const updatedAccount = {
...account, ...account,
@ -126,7 +126,7 @@ export default ({ store, locked }: { store: Object, locked: boolean }) => {
return result return result
}, {}), }, {}),
index: account.index || existingAccount.index, index: account.index || existingAccount.index,
transactions: [...transactions, ...account.transactions], operations: [...operations, ...account.operations],
} }
store.dispatch(updateAccount(updatedAccount)) store.dispatch(updateAccount(updatedAccount))
} }

2
src/renderer/i18n/instanciate.js

@ -14,7 +14,7 @@ const commonConfig = {
'settings', 'settings',
'sidebar', 'sidebar',
'time', 'time',
'transactionsList', 'operationsList',
'update', 'update',
], ],
fallbackLng: 'en', fallbackLng: 'en',

2
src/renderer/i18n/storybook.js

@ -13,7 +13,7 @@ const resources = {
settings: require('../../../static/i18n/en/settings.yml'), settings: require('../../../static/i18n/en/settings.yml'),
sidebar: require('../../../static/i18n/en/sidebar.yml'), sidebar: require('../../../static/i18n/en/sidebar.yml'),
time: require('../../../static/i18n/en/time.yml'), time: require('../../../static/i18n/en/time.yml'),
transactionsList: require('../../../static/i18n/en/transactionsList.yml'), operationsList: require('../../../static/i18n/en/operationsList.yml'),
update: require('../../../static/i18n/en/update.yml'), update: require('../../../static/i18n/en/update.yml'),
} }

11
src/types/common.js

@ -10,18 +10,19 @@ export type Device = {
export type Devices = Array<Device> export type Devices = Array<Device>
// -------------------- Transactions // -------------------- Operations
export type Transaction = { export type Operation = {
id: string,
account?: Account, account?: Account,
address: string, address: string,
balance: number, amount: number,
hash: string, hash: string,
receivedAt: string, receivedAt: string,
confirmations: number, confirmations: number,
} }
export type Transactions = Array<Transaction> export type Operations = Array<Operation>
// -------------------- Accounts // -------------------- Accounts
@ -42,7 +43,7 @@ export type Account = {
name: string, name: string,
path: string, path: string,
rootPath: string, rootPath: string,
transactions: Transactions, operations: Operations,
unit: Unit, unit: Unit,
settings: AccountSettings, settings: AccountSettings,
} }

0
static/i18n/en/transactionsList.yml → static/i18n/en/operationsList.yml

0
static/i18n/fr/transactionsList.yml → static/i18n/fr/operationsList.yml

Loading…
Cancel
Save