Browse Source

Use common currencies list when adding account

master
meriadec 7 years ago
parent
commit
73c7e7b552
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 11
      src/components/AccountPage.js
  2. 4
      src/components/DashboardPage/AccountCard.js
  3. 6
      src/components/DashboardPage/index.js
  4. 5
      src/components/SelectAccount/stories.js
  5. 2
      src/components/SideBar/index.js
  6. 8
      src/components/TransactionsList/index.js
  7. 29
      src/components/base/FormattedVal.js
  8. 76
      src/components/modals/AddAccount/index.js
  9. 15
      src/internals/usb/wallet/index.js
  10. 63
      src/stories/currencies.stories.js
  11. 6
      src/types/common.js

11
src/components/AccountPage.js

@ -39,6 +39,13 @@ const mapDispatchToProps = {
openModal,
}
function enrichTransactionsWithAccount(transactions, account) {
return transactions.map(t => ({
...t,
account,
}))
}
class AccountPage extends PureComponent<Props> {
render() {
const { account, accountData, openModal, t } = this.props
@ -100,7 +107,9 @@ class AccountPage extends PureComponent<Props> {
</Box>
</Box>
<Card p={0} px={4} title={t('AccountPage.lastOperations')}>
<TransactionsList transactions={accountData.transactions} />
<TransactionsList
transactions={enrichTransactionsWithAccount(accountData.transactions, account)}
/>
</Card>
</Fragment>
)}

4
src/components/DashboardPage/AccountCard.js

@ -27,7 +27,7 @@ const AccountCard = ({
</Box>
<Box>
<Box style={{ textTransform: 'uppercase' }} fontSize={0} color="warmGrey">
{account.type}
{account.unit.code}
</Box>
<Box fontSize={4} color="dark">
{account.name}
@ -40,7 +40,7 @@ const AccountCard = ({
<FormattedVal
alwaysShowSign={false}
color="dark"
currency={account.type}
unit={account.unit}
showCode
val={account.data.balance}
/>

6
src/components/DashboardPage/index.js

@ -96,11 +96,7 @@ const getAllTransactions = accounts => {
...result,
...transactions.map(t => ({
...t,
account: {
id: account.id,
name: account.name,
type: account.type,
},
account,
})),
]

5
src/components/SelectAccount/stories.js

@ -3,6 +3,7 @@
import React, { PureComponent } from 'react'
import { storiesOf } from '@storybook/react'
import Chance from 'chance'
import { getCurrencyByCoinType, getDefaultUnitByCoinType } from '@ledgerhq/currencies'
import { SelectAccount } from 'components/SelectAccount'
@ -12,7 +13,9 @@ const stories = storiesOf('SelectAccount', module)
const accounts = [...Array(20)].map(() => ({
id: chance.string(),
name: chance.name(),
type: 'BTC',
coinType: 0,
currency: getCurrencyByCoinType(0),
unit: getDefaultUnitByCoinType(0),
data: {
address: chance.string(),
balance: chance.floating({ min: 0, max: 20 }),

2
src/components/SideBar/index.js

@ -106,7 +106,7 @@ class SideBar extends PureComponent<Props> {
<FormattedVal
alwaysShowSign={false}
color="warmGrey"
currency={account.type}
unit={account.unit}
showCode
val={account.data ? account.data.balance : 0}
/>

8
src/components/TransactionsList/index.js

@ -121,7 +121,13 @@ const Transaction = ({
</Box>
</Cell>
<Cell size={AMOUNT_COL_SIZE} justifyContent="flex-end">
<FormattedVal val={tx.balance} currency="BTC" showCode fontSize={4} alwaysShowSign />
<FormattedVal
val={tx.balance}
unit={tx.account.unit}
showCode
fontSize={4}
alwaysShowSign
/>
</Cell>
</TransactionRaw>
)

29
src/components/base/FormattedVal.js

@ -4,6 +4,7 @@ import React from 'react'
import styled from 'styled-components'
import { formatCurrencyUnit } from '@ledgerhq/currencies'
import type { Unit } from '@ledgerhq/currencies'
import Text from 'components/base/Text'
@ -12,31 +13,16 @@ const T = styled(Text).attrs({
color: p => (p.isNegative ? p.theme.colors.grenade : p.theme.colors.green),
})``
const currencies = {
BTC: {
name: 'bitcoin',
code: 'BTC',
symbol: 'b',
magnitude: 8,
},
USD: {
name: 'dollar',
code: 'USD',
symbol: '$',
magnitude: 0,
},
}
type Props = {
val: number,
isPercent?: boolean,
currency?: any,
unit?: Unit | null,
alwaysShowSign?: boolean,
showCode?: boolean,
}
function FormattedVal(props: Props) {
const { val, isPercent, currency, alwaysShowSign, showCode, ...p } = props
const { val, isPercent, unit, alwaysShowSign, showCode, ...p } = props
const isNegative = val < 0
@ -45,11 +31,10 @@ function FormattedVal(props: Props) {
if (isPercent) {
text = `${alwaysShowSign ? (isNegative ? '- ' : '+ ') : ''}${val} %`
} else {
const curr = currency ? currencies[currency.toUpperCase()] : null
if (!curr) {
return `[invalid currency ${currency || '(null)'}]`
if (!unit) {
return ''
}
text = formatCurrencyUnit(curr, val, {
text = formatCurrencyUnit(unit, val, {
alwaysShowSign,
showCode,
})
@ -63,7 +48,7 @@ function FormattedVal(props: Props) {
}
FormattedVal.defaultProps = {
currency: null,
unit: null,
isPercent: false,
alwaysShowSign: false,
showCode: false,

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

@ -6,6 +6,9 @@ import { compose } from 'redux'
import { translate } from 'react-i18next'
import { ipcRenderer } from 'electron'
import differenceBy from 'lodash/differenceBy'
import { listCurrencies, getDefaultUnitByCoinType } from '@ledgerhq/currencies'
import type { Currency } from '@ledgerhq/currencies'
import { MODAL_ADD_ACCOUNT } from 'constants'
@ -30,25 +33,24 @@ import CreateAccount from './CreateAccount'
import ImportAccounts from './ImportAccounts'
import RestoreAccounts from './RestoreAccounts'
const currencies = [
{
key: 'btc',
name: 'Bitcoin',
},
]
const currencies = listCurrencies().map(currency => ({
key: currency.coinType,
name: currency.name,
data: currency,
}))
const Steps = {
chooseWallet: (props: Object) => (
chooseCurrency: (props: Object) => (
<form onSubmit={props.onSubmit}>
<Box flow={3}>
<Box flow={1}>
<Label>{props.t('common.currency')}</Label>
<Select
placeholder={props.t('common.chooseWalletPlaceholder')}
onChange={item => props.onChangeInput('wallet')(item.key)}
onChange={item => props.onChangeCurrency(item.data)}
renderSelected={item => item.name}
items={currencies}
value={currencies.find(c => c.key === props.value.wallet)}
value={props.currency ? currencies.find(c => c.key === props.currency.coinType) : null}
/>
</Box>
<Box horizontal justifyContent="flex-end">
@ -62,7 +64,7 @@ const Steps = {
connectDevice: (props: Object) => (
<Box>
<Box>Connect your Ledger: {props.connected ? 'ok' : 'ko'}</Box>
<Box>Start {props.wallet.toUpperCase()} App on your Ledger: ko</Box>
<Box>Start {props.currency.name} App on your Ledger: ko</Box>
</Box>
),
inProgress: (props: Object) => (
@ -95,11 +97,7 @@ const Steps = {
},
}
type InputValue = {
wallet: string,
}
type Step = 'chooseWallet' | 'connectDevice' | 'inProgress' | 'listAccounts'
type Step = 'chooseCurrency' | 'connectDevice' | 'inProgress' | 'listAccounts'
type Props = {
t: T,
@ -113,8 +111,8 @@ type Props = {
}
type State = {
inputValue: InputValue,
step: Step,
currency: Currency | null,
accounts: Accounts,
progress: null | Object,
}
@ -133,12 +131,10 @@ const mapDispatchToProps = {
}
const defaultState = {
inputValue: {
wallet: '',
},
currency: null,
accounts: [],
progress: null,
step: 'chooseWallet',
step: 'chooseCurrency',
}
class AddAccountModal extends PureComponent<Props, State> {
@ -176,36 +172,36 @@ class AddAccountModal extends PureComponent<Props, State> {
getWalletInfos() {
const { currentDevice, accounts } = this.props
const { inputValue } = this.state
const { currency } = this.state
if (currentDevice === null) {
if (currentDevice === null || currency === null) {
return
}
sendEvent('usb', 'wallet.getAccounts', {
pathDevice: currentDevice.path,
wallet: inputValue.wallet,
coinType: currency.coinType,
currentAccounts: accounts.map(acc => acc.id),
})
}
getStepProps() {
const { currentDevice, archivedAccounts, canCreateAccount, updateAccount, t } = this.props
const { inputValue, step, progress, accounts } = this.state
const { currency, step, progress, accounts } = this.state
const props = (predicate, props) => (predicate ? props : {})
return {
...props(step === 'chooseWallet', {
...props(step === 'chooseCurrency', {
t,
value: inputValue,
currency,
onChangeCurrency: this.handleChangeCurrency,
onSubmit: this.handleSubmit,
onChangeInput: this.handleChangeInput,
}),
...props(step === 'connectDevice', {
t,
connected: currentDevice !== null,
wallet: inputValue.wallet,
currency,
}),
...props(step === 'inProgress', {
t,
@ -247,23 +243,11 @@ class AddAccountModal extends PureComponent<Props, State> {
handleImportAccounts = accounts => accounts.forEach(account => this.addAccount(account))
handleChangeInput = (key: $Keys<InputValue>) => (value: $Values<InputValue>) =>
this.setState(prev => ({
inputValue: {
...prev.inputValue,
[key]: value,
},
}))
handleChangeCurrency = (currency: Currency) => this.setState({ currency })
handleSubmit = (e: SyntheticEvent<HTMLFormElement>) => {
e.preventDefault()
const { inputValue } = this.state
if (inputValue.wallet.trim() === '') {
return
}
this.setState({
step: 'connectDevice',
})
@ -277,13 +261,19 @@ class AddAccountModal extends PureComponent<Props, State> {
})
addAccount = ({ id, name, ...data }) => {
const { inputValue } = this.state
const { currency } = this.state
const { addAccount } = this.props
if (currency === null) {
return
}
addAccount({
id,
name,
type: inputValue.wallet,
coinType: currency.coinType,
currency,
unit: getDefaultUnitByCoinType(currency.coinType),
data,
})
}

15
src/internals/usb/wallet/index.js

@ -4,30 +4,31 @@ import CommNodeHid from '@ledgerhq/hw-transport-node-hid'
import getAllAccounts, { verifyAddress } from './accounts'
async function getAllAccountsByWallet({ pathDevice, wallet, currentAccounts, onProgress }) {
async function getAllAccountsByCoinType({ pathDevice, coinType, currentAccounts, onProgress }) {
const transport = await CommNodeHid.open(pathDevice)
if (wallet === 'btc') {
// 0: BTC
if (coinType === 0) {
return getAllAccounts({ transport, currentAccounts, onProgress })
}
throw new Error('invalid wallet')
throw new Error('invalid coinType')
}
export default (sendEvent: Function) => ({
getAccounts: async ({
pathDevice,
wallet,
coinType,
currentAccounts,
}: {
pathDevice: string,
wallet: string,
coinType: number,
currentAccounts: Array<*>,
}) => {
try {
const data = await getAllAccountsByWallet({
const data = await getAllAccountsByCoinType({
pathDevice,
wallet,
coinType,
currentAccounts,
onProgress: progress => sendEvent('wallet.getAccounts.progress', progress, { kill: false }),
})

63
src/stories/currencies.stories.js

@ -0,0 +1,63 @@
// @flow
import React, { Fragment, createElement } from 'react'
import { storiesOf } from '@storybook/react'
import { listCurrencies } from '@ledgerhq/currencies'
import type { Currency } from '@ledgerhq/currencies'
const stories = storiesOf('currencies', module)
const currencies: Array<Currency> = listCurrencies()
stories.add('currencies list', () => (
<div>
<table border="1">
<thead>
<tr>
<td>{'coin type'}</td>
<td>{'name'}</td>
<td>{'color'}</td>
<td>{'icon'}</td>
<td>{'units'}</td>
</tr>
</thead>
<tbody>
{currencies.map(cur => (
<tr key={cur.coinType}>
<td>{cur.coinType}</td>
<td>{cur.name}</td>
<td>
{cur.color ? (
<Fragment>
<div
style={{
width: 50,
height: 25,
backgroundColor: cur.color,
}}
/>
<div>{cur.color}</div>
</Fragment>
) : (
'-'
)}
</td>
<td>{cur.icon ? createElement(cur.icon, { size: 30 }) : '-'}</td>
<td>
{cur.units && (
<ul style={{ paddingRight: 10 }}>
{cur.units.map(unit => (
<li key={unit.code}>
{unit.code} ({unit.magnitude})
</li>
))}
</ul>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
))

6
src/types/common.js

@ -1,5 +1,7 @@
// @flow
import type { Unit, Currency } from '@ledgerhq/currencies'
export type Device = {
vendorId: string,
productId: string,
@ -32,7 +34,9 @@ export type Account = {
data?: AccountData,
id: string,
name: string,
type: string,
coinType: number,
currency: Currency,
unit: Unit,
}
export type Accounts = Array<Account>

Loading…
Cancel
Save