Browse Source

Merge pull request #432 from gre/fix-eth

important bugfix on ETH + integrate more currencies unit
master
Gaëtan Renaudeau 7 years ago
committed by GitHub
parent
commit
450048aeb4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      package.json
  2. 22
      src/api/Ethereum.js
  3. 33
      src/bridge/EthereumJSBridge.js
  4. 36
      src/components/AdvancedOptions/EthereumKind.js
  5. 2
      src/components/FeesField/EthereumKind.js
  6. 1
      src/components/modals/Send/SendModalBody.js
  7. 4
      src/helpers/signTransactionForCurrency/ethereum.js
  8. 1
      static/i18n/en/send.yml
  9. 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.4.1",
"@ledgerhq/live-common": "2.22.0",
"@ledgerhq/live-common": "2.23.0",
"axios": "^0.18.0",
"babel-runtime": "^6.26.0",
"bcryptjs": "^2.4.3",

22
src/api/Ethereum.js

@ -46,31 +46,35 @@ export const apiForCurrency = (currency: CryptoCurrency): API => {
return {
async getTransactions(address, blockHash) {
const { data } = await userFriendlyError(
axios.get(`${baseURL}/addresses/${address}/transactions`, {
params: { blockHash, noToken: 1 },
}),
retry(
() =>
axios.get(`${baseURL}/addresses/${address}/transactions`, {
params: { blockHash, noToken: 1 },
}),
{ maxRetry: 3 },
),
)
return data
},
async getCurrentBlock() {
const { data } = await userFriendlyError(retry(() => axios.get(`${baseURL}/blocks/current`)))
const { data } = await userFriendlyError(
retry(() => axios.get(`${baseURL}/blocks/current`), { maxRetry: 3 }),
)
return data
},
async getAccountNonce(address) {
const { data } = await userFriendlyError(
retry(() => axios.get(`${baseURL}/addresses/${address}/nonce`)),
retry(() => axios.get(`${baseURL}/addresses/${address}/nonce`), { maxRetry: 3 }),
)
return data[0].nonce
},
async broadcastTransaction(tx) {
const { data } = await userFriendlyError(
retry(() => axios.post(`${baseURL}/transactions/send`, { tx })),
)
const { data } = await userFriendlyError(axios.post(`${baseURL}/transactions/send`, { tx }))
return data.result
},
async getAccountBalance(address) {
const { data } = await userFriendlyError(
retry(() => axios.get(`${baseURL}/addresses/${address}/balance`)),
retry(() => axios.get(`${baseURL}/addresses/${address}/balance`), { maxRetry: 3 }),
)
return data[0].balance
},

33
src/bridge/EthereumJSBridge.js

@ -1,6 +1,7 @@
// @flow
import React from 'react'
import EthereumKind from 'components/FeesField/EthereumKind'
import FeesField from 'components/FeesField/EthereumKind'
import AdvancedOptions from 'components/AdvancedOptions/EthereumKind'
import throttle from 'lodash/throttle'
import flatMap from 'lodash/flatMap'
import uniqBy from 'lodash/uniqBy'
@ -14,10 +15,15 @@ import type { EditProps, WalletBridge } from './types'
// TODO in future it would be neat to support eip55
type Transaction = *
type Transaction = {
amount: number,
recipient: string,
gasPrice: number,
gasLimit: number,
}
const EditFees = ({ account, onChange, value }: EditProps<Transaction>) => (
<EthereumKind
<FeesField
onChange={gasPrice => {
onChange({ ...value, gasPrice })
}}
@ -26,6 +32,15 @@ const EditFees = ({ account, onChange, value }: EditProps<Transaction>) => (
/>
)
const EditAdvancedOptions = ({ onChange, value }: EditProps<Transaction>) => (
<AdvancedOptions
gasLimit={value.gasLimit}
onChange={gasLimit => {
onChange({ ...value, gasLimit })
}}
/>
)
// in case of a SELF send, 2 ops are returned.
const txToOps = (account: Account) => (tx: Tx): Operation[] => {
const freshAddress = account.freshAddress.toLowerCase()
@ -174,7 +189,6 @@ const EthereumBridge: WalletBridge<Transaction> = {
}
txs.reverse()
account.operations = mergeOps([], flatMap(txs, txToOps(account)))
console.log(account)
return { account }
}
@ -270,6 +284,7 @@ const EthereumBridge: WalletBridge<Transaction> = {
amount: 0,
recipient: '',
gasPrice: 0,
gasLimit: 0x5208,
}),
editTransactionAmount: (account, t, amount) => ({
@ -291,10 +306,12 @@ const EthereumBridge: WalletBridge<Transaction> = {
// $FlowFixMe
EditFees,
// FIXME gasPrice calc is wrong... need to multiply with gasLimit I guess ?
canBeSpent: (a, t) => Promise.resolve(t.amount + t.gasPrice <= a.balance),
getTotalSpent: (a, t) => Promise.resolve(t.amount + t.gasPrice),
getMaxAmount: (a, t) => Promise.resolve(a.balance - t.gasPrice),
// $FlowFixMe
EditAdvancedOptions,
canBeSpent: (a, t) => Promise.resolve(t.amount <= a.balance),
getTotalSpent: (a, t) => Promise.resolve(t.amount + t.gasPrice * t.gasLimit),
getMaxAmount: (a, t) => Promise.resolve(a.balance - t.gasPrice * t.gasLimit),
signAndBroadcast: async (a, t, deviceId) => {
const api = apiForCurrency(a.currency)

36
src/components/AdvancedOptions/EthereumKind.js

@ -0,0 +1,36 @@
// @flow
import React from 'react'
import { translate } from 'react-i18next'
import Box from 'components/base/Box'
import Input from 'components/base/Input'
import Label from 'components/base/Label'
import Spoiler from 'components/base/Spoiler'
type Props = {
gasLimit: number,
onChangeGasLimit: (?number) => void,
t: *,
}
export default translate()(({ gasLimit, onChangeGasLimit, t }: Props) => (
<Spoiler title="Advanced options">
<Box horizontal align="center" flow={5}>
<Box style={{ width: 200 }}>
<Label>
<span>{t('send:steps.amount.ethereumGasLimit')}</span>
</Label>
</Box>
<Box grow>
<Input
value={gasLimit}
onChange={str => {
const gasLimit = parseInt(str, 10)
if (!isNaN(gasLimit) && isFinite(gasLimit)) onChangeGasLimit(gasLimit)
else onChangeGasLimit(0x5208)
}}
/>
</Box>
</Box>
</Spoiler>
))

2
src/components/FeesField/EthereumKind.js

@ -34,7 +34,7 @@ class FeesField extends Component<Props & { fees?: Fees, error?: Error }, *> {
return (
<GenericContainer error={error} help="Gas">
<InputCurrency
defaultUnit={units[1]}
defaultUnit={units.length > 1 ? units[1] : units[0]}
units={units}
containerProps={{ grow: true }}
value={gasPrice}

1
src/components/modals/Send/SendModalBody.js

@ -127,6 +127,7 @@ class SendModalBody extends PureComponent<Props, State<*>> {
this.setState({
appStatus: null,
deviceSelected: null,
error: null,
stepIndex: step.prevStep,
})
}

4
src/helpers/signTransactionForCurrency/ethereum.js

@ -27,6 +27,7 @@ export default async (
nonce: string,
recipient: string,
gasPrice: number,
gasLimit: number,
amount: number,
},
) => {
@ -34,11 +35,10 @@ export default async (
const chainId = getNetworkId(currencyId)
if (!chainId) throw new Error(`chainId not found for currency=${currencyId}`)
const gasLimit = '0x5208' // cost of a simple send
const tx = new EthereumTx({
nonce: t.nonce,
gasPrice: `0x${t.gasPrice.toString(16)}`,
gasLimit,
gasLimit: `0x${t.gasLimit.toString(16)}`,
to: t.recipient,
value: `0x${t.amount.toString(16)}`,
chainId,

1
static/i18n/en/send.yml

@ -12,6 +12,7 @@ steps:
useRBF: Use the RBF transaction
message: Leave a message (140)
rippleTag: Tag
ethereumGasLimit: Gas limit
connectDevice:
title: Connect device
verification:

6
yarn.lock

@ -1495,9 +1495,9 @@
npm "^5.7.1"
prebuild-install "^2.2.2"
"@ledgerhq/live-common@2.22.0":
version "2.22.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.22.0.tgz#f958ee28cc09af40a6bed484e73204f01b54d709"
"@ledgerhq/live-common@2.23.0":
version "2.23.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-2.23.0.tgz#c039bbb444ceb909fa9c7f17645c39d9c3ce125e"
dependencies:
axios "^0.18.0"
invariant "^2.2.2"

Loading…
Cancel
Save