Browse Source

Porting to new live-common with changes in Account/Operation

master
Gaëtan Renaudeau 7 years ago
parent
commit
acf0db75b3
  1. 2
      package.json
  2. 51
      src/bridge/EthereumJSBridge.js
  3. 54
      src/bridge/RippleJSBridge.js
  4. 9
      src/bridge/makeMockBridge.js
  5. 2
      src/components/CurrentAddress/stories.js
  6. 9
      src/components/CurrentAddressForAccount.js
  7. 12
      src/components/DeviceCheckAddress.js
  8. 8
      src/components/EnsureDeviceApp/index.js
  9. 12
      src/components/OperationsList/ConfirmationCheck.js
  10. 33
      src/components/OperationsList/Operation.js
  11. 11
      src/components/modals/OperationDetails.js
  12. 2
      src/components/modals/Send/04-step-confirmation.js
  13. 48
      src/internals/accounts/scanAccountsOnDevice.js
  14. 2
      src/internals/accounts/signAndBroadcastTransaction/btc.js
  15. 4
      static/i18n/en/operationsList.yml
  16. 4
      static/i18n/fr/operationsList.yml
  17. 6
      yarn.lock

2
package.json

@ -42,7 +42,7 @@
"@ledgerhq/hw-transport": "^4.12.0",
"@ledgerhq/hw-transport-node-hid": "^4.12.0",
"@ledgerhq/ledger-core": "^1.2.0",
"@ledgerhq/live-common": "^2.7.5",
"@ledgerhq/live-common": "2.8.0-beta.2",
"axios": "^0.18.0",
"babel-runtime": "^6.26.0",
"bcryptjs": "^2.4.3",

51
src/bridge/EthereumJSBridge.js

@ -24,15 +24,17 @@ const EditFees = ({ account, onChange, value }: EditProps<Transaction>) => (
/>
)
const toAccountOperation = (account: Account) => (tx: Tx): Operation => {
const sending = account.address.toLowerCase() === tx.from.toLowerCase()
const toAccountOperation = (account: Account) => (tx: Tx): $Exact<Operation> => {
const sending = account.freshAddress.toLowerCase() === tx.from.toLowerCase()
const receiving = account.freshAddress.toLowerCase() === tx.to.toLowerCase()
const type = sending && receiving ? 'SELF' : sending ? 'OUT' : 'IN'
return {
id: tx.hash,
hash: tx.hash,
address: sending ? tx.to : tx.from,
amount: (sending ? -1 : 1) * tx.value,
blockHeight: (tx.block && tx.block.height) || 0, // FIXME will be optional field
blockHash: (tx.block && tx.block.hash) || '', // FIXME will be optional field
type,
value: tx.value,
blockHeight: tx.block && tx.block.height,
blockHash: tx.block && tx.block.hash,
accountId: account.id,
senders: [tx.from],
recipients: [tx.to],
@ -56,7 +58,7 @@ const paginateMoreTransactions = async (
): Promise<Operation[]> => {
const api = apiForCurrency(account.currency)
const { txs } = await api.getTransactions(
account.address,
account.freshAddress,
acc.length ? acc[acc.length - 1].blockHash : undefined,
)
if (txs.length === 0) return acc
@ -93,7 +95,7 @@ const EthereumBridge: WalletBridge<Transaction> = {
async function stepAddress(
index,
{ address, path },
{ address, path: freshAddressPath },
isStandard,
): { account?: Account, complete?: boolean } {
const balance = await api.getAccountBalance(address)
@ -103,6 +105,9 @@ const EthereumBridge: WalletBridge<Transaction> = {
const { txs } = await api.getTransactions(address)
if (finished) return { complete: true }
const path = freshAddressPath // FIXME
const freshAddress = address
if (txs.length === 0) {
// this is an empty account
if (isStandard) {
@ -110,21 +115,20 @@ const EthereumBridge: WalletBridge<Transaction> = {
// first zero account will emit one account as opportunity to create a new account..
const currentBlock = await fetchCurrentBlock(currency)
const accountId = `${currency.id}_${address}`
const account: Account = {
const account: $Exact<Account> = {
id: accountId,
xpub: '',
path, // FIXME we probably not want the address path in the account.path
walletPath: String(index),
freshAddress,
freshAddressPath,
name: 'New Account',
isSegwit: false,
address,
addresses: [{ str: address, path }],
balance,
blockHeight: currentBlock.height,
archived: true,
index,
currency,
operations: [],
pendingOperations: [],
unit: currency.units[0],
lastSyncDate: new Date(),
}
@ -137,21 +141,20 @@ const EthereumBridge: WalletBridge<Transaction> = {
}
const accountId = `${currency.id}_${address}`
const account: Account = {
const account: $Exact<Account> = {
id: accountId,
xpub: '',
path, // FIXME we probably not want the address path in the account.path
walletPath: String(index),
freshAddress,
freshAddressPath,
name: address.slice(32),
isSegwit: false,
address,
addresses: [{ str: address, path }],
balance,
blockHeight: currentBlock.height,
archived: true,
index,
currency,
operations: [],
pendingOperations: [],
unit: currency.units[0],
lastSyncDate: new Date(),
}
@ -166,9 +169,9 @@ const EthereumBridge: WalletBridge<Transaction> = {
for (const derivation of derivations) {
const isStandard = last === derivation
for (let index = 0; index < 255; index++) {
const path = derivation({ currency, x: index, segwit: false })
const freshAddressPath = derivation({ currency, x: index, segwit: false })
const res = await getAddressCommand
.send({ currencyId: currency.id, devicePath: deviceId, path })
.send({ currencyId: currency.id, devicePath: deviceId, path: freshAddressPath })
.toPromise()
const r = await stepAddress(index, res, isStandard)
if (r.account) next(r.account)
@ -188,7 +191,7 @@ const EthereumBridge: WalletBridge<Transaction> = {
return { unsubscribe }
},
synchronize({ address, blockHeight, currency }, { next, complete, error }) {
synchronize({ freshAddress, blockHeight, currency }, { next, complete, error }) {
let unsubscribed = false
const api = apiForCurrency(currency)
async function main() {
@ -198,9 +201,9 @@ const EthereumBridge: WalletBridge<Transaction> = {
if (block.height === blockHeight) {
complete()
} else {
const balance = await api.getAccountBalance(address)
const balance = await api.getAccountBalance(freshAddress)
if (unsubscribed) return
const { txs } = await api.getTransactions(address)
const { txs } = await api.getTransactions(freshAddress)
if (unsubscribed) return
next(a => {
const currentOps = a.operations
@ -277,7 +280,7 @@ const EthereumBridge: WalletBridge<Transaction> = {
signAndBroadcast: async (a, t, deviceId) => {
const api = apiForCurrency(a.currency)
const nonce = await api.getAccountNonce(a.address)
const nonce = await api.getAccountNonce(a.freshAddress)
const transaction = await signTransactionCommand
.send({

54
src/bridge/RippleJSBridge.js

@ -122,19 +122,18 @@ const txToOperation = (account: Account) => ({
outcome: { deliveredAmount, ledgerVersion, timestamp },
specification: { source, destination },
}: Tx): Operation => {
const sending = source.address === account.address
const amount =
(sending ? -1 : 1) * (deliveredAmount ? parseAPICurrencyObject(deliveredAmount) : 0)
const op: Operation = {
const type = source.address === account.freshAddress ? 'OUT' : 'IN'
const value = deliveredAmount ? parseAPICurrencyObject(deliveredAmount) : 0
const op: $Exact<Operation> = {
id,
hash: id,
accountId: account.id,
blockHash: '',
address: sending ? destination.address : source.address,
amount,
type,
value,
blockHash: null,
blockHeight: ledgerVersion,
senders: [sending ? destination.address : source.address],
recipients: [!sending ? destination.address : source.address],
senders: [source.address],
recipients: [destination.address],
date: new Date(timestamp),
}
return op
@ -159,9 +158,11 @@ const RippleJSBridge: WalletBridge<Transaction> = {
const derivations = getDerivations(currency)
for (const derivation of derivations) {
for (let index = 0; index < 255; index++) {
const path = derivation({ currency, x: index, segwit: false })
const freshAddressPath = derivation({ currency, x: index, segwit: false })
const path = freshAddressPath
// FIXME^ we need the account path, not the address path
const { address } = await await getAddress
.send({ currencyId: currency.id, devicePath: deviceId, path })
.send({ currencyId: currency.id, devicePath: deviceId, path: freshAddressPath })
.toPromise()
if (finished) return
@ -176,6 +177,9 @@ const RippleJSBridge: WalletBridge<Transaction> = {
}
}
// fresh address is address. ripple never changes.
const freshAddress = address
if (!info) {
// account does not exist in Ripple server
// we are generating a new account locally
@ -183,16 +187,15 @@ const RippleJSBridge: WalletBridge<Transaction> = {
id: accountId,
xpub: '',
path,
walletPath: '',
name: 'New Account',
isSegwit: false,
address,
addresses: [address],
freshAddress,
freshAddressPath,
balance: 0,
blockHeight: maxLedgerVersion,
index,
currency,
operations: [],
pendingOperations: [],
unit: currency.units[0],
archived: true,
lastSyncDate: new Date(),
@ -212,20 +215,19 @@ const RippleJSBridge: WalletBridge<Transaction> = {
})
if (finished) return
const account: Account = {
const account: $Exact<Account> = {
id: accountId,
xpub: '',
path,
walletPath: '',
name: address.slice(0, 8),
isSegwit: false,
address,
addresses: [address],
freshAddress,
freshAddressPath,
balance,
blockHeight: maxLedgerVersion,
index,
currency,
operations: [],
pendingOperations: [],
unit: currency.units[0],
archived: true,
lastSyncDate: new Date(),
@ -247,7 +249,7 @@ const RippleJSBridge: WalletBridge<Transaction> = {
return { unsubscribe }
},
synchronize({ currency, address, blockHeight }, { next, error, complete }) {
synchronize({ currency, freshAddress, blockHeight }, { next, error, complete }) {
let finished = false
const unsubscribe = () => {
finished = true
@ -266,7 +268,7 @@ const RippleJSBridge: WalletBridge<Transaction> = {
let info
try {
info = await api.getAccountInfo(address)
info = await api.getAccountInfo(freshAddress)
} catch (e) {
if (e.message !== 'actNotFound') {
throw e
@ -282,12 +284,12 @@ const RippleJSBridge: WalletBridge<Transaction> = {
const balance = parseAPIValue(info.xrpBalance)
if (isNaN(balance) || !isFinite(balance)) {
throw new Error(`Ripple: invalid balance=${balance} for address ${address}`)
throw new Error(`Ripple: invalid balance=${balance} for address ${freshAddress}`)
}
next(a => ({ ...a, balance }))
const transactions = await api.getTransactions(address, {
const transactions = await api.getTransactions(freshAddress, {
minLedgerVersion: Math.max(blockHeight, minLedgerVersion),
maxLedgerVersion,
})
@ -362,7 +364,7 @@ const RippleJSBridge: WalletBridge<Transaction> = {
const amount = formatAPICurrencyXRP(t.amount)
const payment = {
source: {
address: a.address,
address: a.freshAddress,
amount,
},
destination: {
@ -375,7 +377,7 @@ const RippleJSBridge: WalletBridge<Transaction> = {
fee: formatAPICurrencyXRP(t.fee).value,
}
const prepared = await api.preparePayment(a.address, payment, instruction)
const prepared = await api.preparePayment(a.freshAddress, payment, instruction)
const transaction = await signTransaction
.send({

9
src/bridge/makeMockBridge.js

@ -4,6 +4,7 @@ import {
genAddingOperationsInAccount,
genOperation,
} from '@ledgerhq/live-common/lib/mock/account'
import { getOperationAmountNumber } from '@ledgerhq/live-common/lib/helpers/operation'
import Prando from 'prando'
import type { Operation } from '@ledgerhq/live-common/lib/types'
import type { WalletBridge } from './types'
@ -53,7 +54,7 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
account = { ...account }
account.blockHeight++
for (const op of ops) {
account.balance += op.amount
account.balance += getOperationAmountNumber(op)
}
return account
})
@ -149,8 +150,10 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
signAndBroadcast: async (account, t) => {
const rng = new Prando()
const op = genOperation(account, account.operations, account.currency, rng)
op.amount = -t.amount
op.address = t.recipient
op.type = 'OUT'
op.value = t.amount
op.senders = [account.freshAddress]
op.recipients = [t.recipient]
op.blockHeight = account.blockHeight
op.date = new Date()
broadcasted[account.id] = (broadcasted[account.id] || []).concat(op)

2
src/components/CurrentAddress/stories.js

@ -13,7 +13,7 @@ const stories = storiesOf('Components', module)
stories.add('CurrentAddress', () => (
<CurrentAddress
accountName={text('accountName', '')}
address={accounts[0].address}
address={accounts[0].freshAddress}
addressVerified={boolean('addressVerified', true)}
withBadge={boolean('withBadge', false)}
withFooter={boolean('withFooter', false)}

9
src/components/CurrentAddressForAccount.js

@ -11,12 +11,5 @@ type Props = {
export default function CurrentAddressForAccount(props: Props) {
const { account, ...p } = props
// TODO: handle other cryptos than BTC-like
let freshAddress = account.addresses[0]
if (!freshAddress) {
freshAddress = { str: '', path: '' }
}
return <CurrentAddress accountName={account.name} address={freshAddress.str} {...p} />
return <CurrentAddress accountName={account.name} address={account.freshAddress} {...p} />
}

12
src/components/DeviceCheckAddress.js

@ -42,23 +42,17 @@ class CheckAddress extends PureComponent<Props, State> {
verifyAddress = async ({ device, account }: { device: Device, account: Account }) => {
try {
// TODO: this will work only for BTC-like accounts
const freshAddress = account.addresses[0]
if (!freshAddress) {
throw new Error('Account doesnt have fresh addresses')
}
const { address } = await getAddress
.send({
currencyId: account.currency.id,
devicePath: device.path,
path: freshAddress.path,
segwit: account.isSegwit,
path: account.freshAddressPath,
segwit: !!account.isSegwit,
verify: true,
})
.toPromise()
if (address !== freshAddress.str) {
if (address !== account.freshAddress) {
throw new Error('Confirmed address is different')
}

8
src/components/EnsureDeviceApp/index.js

@ -102,9 +102,9 @@ class EnsureDeviceApp extends PureComponent<Props, State> {
options = {
devicePath: deviceSelected.path,
currencyId: account.currency.id,
path: account.path,
accountAddress: account.address,
segwit: account.path.startsWith("49'"), // TODO: store segwit info in account
path: account.freshAddressPath,
accountAddress: account.freshAddress,
segwit: !!account.isSegwit,
}
} else if (currency) {
options = {
@ -118,7 +118,7 @@ class EnsureDeviceApp extends PureComponent<Props, State> {
try {
const { address } = await getAddress.send(options).toPromise()
if (account && account.address !== address) {
if (account && account.freshAddress !== address) {
throw new Error('Account address is different than device address')
}
this.handleStatusChange(this.state.deviceStatus, 'success')

12
src/components/OperationsList/ConfirmationCheck.js

@ -3,6 +3,8 @@
import React from 'react'
import styled from 'styled-components'
import type { OperationType } from '@ledgerhq/live-common/lib/types'
import { rgba } from 'styles/helpers'
import type { T } from 'types/common'
@ -16,14 +18,14 @@ import Tooltip from 'components/base/Tooltip'
const Container = styled(Box).attrs({
bg: p =>
p.isConfirmed ? rgba(p.type === 'from' ? p.marketColor : p.theme.colors.grey, 0.2) : 'none',
color: p => (p.type === 'from' ? p.marketColor : p.theme.colors.grey),
p.isConfirmed ? rgba(p.type === 'IN' ? p.marketColor : p.theme.colors.grey, 0.2) : 'none',
color: p => (p.type === 'IN' ? p.marketColor : p.theme.colors.grey),
align: 'center',
justify: 'center',
})`
border: ${p =>
!p.isConfirmed
? `1px solid ${p.type === 'from' ? p.marketColor : rgba(p.theme.colors.grey, 0.2)}`
? `1px solid ${p.type === 'IN' ? p.marketColor : rgba(p.theme.colors.grey, 0.2)}`
: 0};
border-radius: 50%;
position: relative;
@ -55,14 +57,14 @@ const ConfirmationCheck = ({
confirmations: number,
minConfirmations: number,
t: T,
type: 'to' | 'from',
type: OperationType,
withTooltip?: boolean,
}) => {
const isConfirmed = confirmations >= minConfirmations
const renderContent = () => (
<Container type={type} isConfirmed={isConfirmed} marketColor={marketColor} {...props}>
{type === 'from' ? <IconReceive size={12} /> : <IconSend size={12} />}
{type === 'IN' ? <IconReceive size={12} /> : <IconSend size={12} />}
{!isConfirmed && (
<WrapperClock>
<IconClock size={10} />

33
src/components/OperationsList/Operation.js

@ -7,8 +7,9 @@ import { createStructuredSelector } from 'reselect'
import moment from 'moment'
import noop from 'lodash/noop'
import { getCryptoCurrencyIcon } from '@ledgerhq/live-common/lib/react'
import { getOperationAmountNumber } from '@ledgerhq/live-common/lib/helpers/operation'
import type { Account, Operation as OperationType } from '@ledgerhq/live-common/lib/types'
import type { Account, Operation } from '@ledgerhq/live-common/lib/types'
import type { T } from 'types/common'
@ -103,15 +104,15 @@ const Cell = styled(Box).attrs({
type Props = {
account: Account,
currencySettings: *,
onAccountClick: Function,
onOperationClick: Function,
onAccountClick: (account: Account) => void,
onOperationClick: ({ operation: Operation, account: Account, marketColor: string }) => void,
marketIndicator: string,
t: T,
op: OperationType,
op: Operation, // FIXME rename it operation
withAccount: boolean,
}
class Operation extends PureComponent<Props> {
class OperationComponent extends PureComponent<Props> {
static defaultProps = {
onAccountClick: noop,
onOperationClick: noop,
@ -132,8 +133,8 @@ class Operation extends PureComponent<Props> {
const { unit, currency } = account
const time = moment(op.date)
const Icon = getCryptoCurrencyIcon(account.currency)
const isNegative = op.amount < 0
const type = !isNegative ? 'from' : 'to'
const amount = getOperationAmountNumber(op)
const isNegative = amount < 0
const marketColor = getMarketColor({
marketIndicator,
@ -141,12 +142,12 @@ class Operation extends PureComponent<Props> {
})
return (
<OperationRaw onClick={() => onOperationClick({ operation: op, account, type, marketColor })}>
<OperationRaw onClick={() => onOperationClick({ operation: op, account, marketColor })}>
<Cell size={CONFIRMATION_COL_SIZE} align="center" justify="flex-start">
<ConfirmationCheck
type={type}
type={op.type}
minConfirmations={currencySettings.minConfirmations}
confirmations={account.blockHeight - op.blockHeight}
confirmations={op.blockHeight ? account.blockHeight - op.blockHeight : 0}
marketColor={marketColor}
t={t}
/>
@ -154,7 +155,7 @@ class Operation extends PureComponent<Props> {
<Cell size={DATE_COL_SIZE} justifyContent="space-between" px={3}>
<Box>
<Box ff="Open Sans|SemiBold" fontSize={3} color="smoke">
{t(`operationsList:${type}`)}
{t(`operationsList:${op.type}`)}
</Box>
<Hour>{time.format('HH:mm')}</Hour>
</Box>
@ -185,24 +186,24 @@ class Operation extends PureComponent<Props> {
</Cell>
)}
<Cell grow shrink style={{ display: 'block' }}>
<Address value={op.address} />
<Address value={op.type === 'IN' ? op.senders[0] : op.recipients[0]} />
</Cell>
<Cell size={AMOUNT_COL_SIZE} justify="flex-end">
<Box alignItems="flex-end">
<FormattedVal
val={op.amount}
val={amount}
unit={unit}
showCode
fontSize={4}
alwaysShowSign
color={op.amount < 0 ? 'smoke' : undefined}
color={amount < 0 ? 'smoke' : undefined}
/>
<CounterValue
color="grey"
fontSize={3}
date={time.toDate()}
currency={currency}
value={op.amount}
value={amount}
exchange={currencySettings.exchange}
/>
</Box>
@ -212,4 +213,4 @@ class Operation extends PureComponent<Props> {
}
}
export default connect(mapStateToProps)(Operation)
export default connect(mapStateToProps)(OperationComponent)

11
src/components/modals/OperationDetails.js

@ -6,6 +6,7 @@ import { shell } from 'electron'
import { translate } from 'react-i18next'
import styled from 'styled-components'
import moment from 'moment'
import { getOperationAmountNumber } from '@ledgerhq/live-common/lib/helpers/operation'
import type { Account, Operation } from '@ledgerhq/live-common/lib/types'
import type { T } from 'types/common'
@ -61,18 +62,18 @@ type Props = {
t: T,
operation: Operation,
account: Account,
type: 'from' | 'to',
onClose: Function,
onClose: () => void,
currencySettings: *,
marketColor: string,
}
const OperationDetails = connect(mapStateToProps)((props: Props) => {
const { t, type, onClose, operation, account, marketColor, currencySettings } = props
const { id, hash, amount, date, senders, recipients } = operation
const { t, onClose, operation, account, marketColor, currencySettings } = props
const { id, hash, date, senders, recipients, type } = operation
const amount = getOperationAmountNumber(operation)
const { name, unit, currency } = account
const confirmations = account.blockHeight - operation.blockHeight
const confirmations = operation.blockHeight ? account.blockHeight - operation.blockHeight : 0
const isConfirmed = confirmations >= currencySettings.minConfirmations
return (
<ModalBody onClose={onClose}>

2
src/components/modals/Send/04-step-confirmation.js

@ -53,7 +53,7 @@ function StepConfirmation(props: Props) {
</span>
<Title>{t(`${tPrefix}.title`)}</Title>
<Text>{multiline(t(`${tPrefix}.text`))}</Text>
<Text>{txValidated || ''}</Text>
<Text style={{ userSelect: 'text' }}>{txValidated || ''}</Text>
</Container>
)
}

48
src/internals/accounts/scanAccountsOnDevice.js

@ -14,7 +14,7 @@ import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/helpers/currenc
import type Transport from '@ledgerhq/hw-transport'
import type { AccountRaw } from '@ledgerhq/live-common/lib/types'
import type { AccountRaw, OperationRaw, OperationType } from '@ledgerhq/live-common/lib/types'
import type { NJSAccount, NJSOperation } from '@ledgerhq/ledger-core/src/ledgercore_doc'
type Props = {
@ -211,6 +211,7 @@ async function buildAccountRaw({
// $FlowFixMe
ops: NJSOperation[],
}): Promise<AccountRaw> {
/*
const balanceByDay = ops.length
? await getBalanceByDaySinceOperation({
njsAccount,
@ -218,6 +219,7 @@ async function buildAccountRaw({
core,
})
: {}
*/
const njsBalance = await njsAccount.getBalance()
const balance = njsBalance.toLong()
@ -244,23 +246,28 @@ async function buildAccountRaw({
path: `${accountPath}/${njsAddress.getDerivationPath()}`,
}))
if (addresses.length === 0) {
throw new Error('no addresses found')
}
const { str: freshAddress, path: freshAddressPath } = addresses[0]
const operations = ops.map(op => buildOperationRaw({ core, op, xpub }))
const rawAccount: AccountRaw = {
id: xpub,
id: xpub, // FIXME for account id you might want to prepend the crypto currency id to this because it's not gonna be unique.
xpub,
path: accountPath,
walletPath,
path: walletPath,
name: `Account ${accountIndex}${isSegwit ? ' (segwit)' : ''}`, // TODO: placeholder name?
isSegwit,
address: bitcoinAddress,
addresses,
freshAddress,
freshAddressPath,
balance,
blockHeight,
archived: false,
index: accountIndex,
balanceByDay,
operations,
pendingOperations: [],
currencyId,
unitMagnitude: jsCurrency.units[0].magnitude,
lastSyncDate: new Date().toISOString(),
@ -269,31 +276,45 @@ async function buildAccountRaw({
return rawAccount
}
function buildOperationRaw({ core, op, xpub }: { core: Object, op: NJSOperation, xpub: string }) {
function buildOperationRaw({
core,
op,
xpub,
}: {
core: Object,
op: NJSOperation,
xpub: string,
}): OperationRaw {
const id = op.getUid()
const bitcoinLikeOperation = op.asBitcoinLikeOperation()
const bitcoinLikeTransaction = bitcoinLikeOperation.getTransaction()
const hash = bitcoinLikeTransaction.getHash()
const operationType = op.getOperationType()
const absoluteAmount = op.getAmount().toLong()
const value = op.getAmount().toLong()
const OperationTypeMap: { [_: $Keys<typeof core.OPERATION_TYPES>]: OperationType } = {
[core.OPERATION_TYPES.SEND]: 'OUT',
[core.OPERATION_TYPES.RECEIVE]: 'IN',
}
// if transaction is a send, amount becomes negative
const amount = operationType === core.OPERATION_TYPES.SEND ? -absoluteAmount : absoluteAmount
const type = OperationTypeMap[operationType]
return {
id,
hash,
address: '',
type,
value,
senders: op.getSenders(),
recipients: op.getRecipients(),
blockHeight: op.getBlockHeight(),
blockHash: '',
blockHash: null,
accountId: xpub,
date: op.getDate().toISOString(),
amount,
}
}
/*
async function getBalanceByDaySinceOperation({
njsAccount,
njsOperation,
@ -336,3 +357,4 @@ function areSameDay(date1: Date, date2: Date): boolean {
date1.getDate() === date2.getDate()
)
}
*/

2
src/internals/accounts/signAndBroadcastTransaction/btc.js

@ -37,7 +37,7 @@ export default async function signAndBroadcastTransactionBTCLike(
const WALLET_IDENTIFIER = await getWalletIdentifier({
hwApp,
isSegwit: account.isSegwit,
isSegwit: !!account.isSegwit,
currencyId: account.currencyId,
devicePath: deviceId,
})

4
static/i18n/en/operationsList.yml

@ -2,8 +2,8 @@ date: Date
account: Account
address: Address
amount: Amount
from: Receive funds
to: Sent funds
IN: Receive funds
OUT: Sent funds
showMore: Show more
confirmed: Confirmed
notConfirmed: Not confirmed

4
static/i18n/fr/operationsList.yml

@ -3,8 +3,8 @@ date: Date
account: Compte
address: Adresse
amount: Montant
from: Fonds reçus
to: Fonds envoyés
IN: Fonds reçus
OUT: Fonds envoyés
showMore: Voir plus
confirmed: Confirmée
notConfirmed: Non confirmée

6
yarn.lock

@ -1480,9 +1480,9 @@
npm "^5.7.1"
prebuild-install "^2.2.2"
"@ledgerhq/live-common@^2.7.5":
version "2.7.5"
resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.7.5.tgz#5434bf2e708aaca471be4ca823e613cf27ba700c"
"@ledgerhq/live-common@2.8.0-beta.2":
version "2.8.0-beta.2"
resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.8.0-beta.2.tgz#942c457ee01add58752698fd525f45abdcf4597b"
dependencies:
axios "^0.18.0"
invariant "^2.2.2"

Loading…
Cancel
Save