@@ -5,6 +5,7 @@ import Tx from 'ethereumjs-tx'
5import Web3 from 'web3'
5import Web3 from 'web3'
7import { BRIDGE_ERROR } from '../lib/error'
7import { BRIDGE_ERROR } from '../lib/error'
8+import { NETWORK_NAMES } from '../lib/network'
8import { ledgerSignTransaction } from '../lib/ledger'
9import { ledgerSignTransaction } from '../lib/ledger'
9import { trezorSignTransaction } from '../lib/trezor'
10import { trezorSignTransaction } from '../lib/trezor'
@@ -48,6 +49,7 @@ const signTransaction = async config => {
49 walletType,
50 walletType,
50 walletHdPath,
51 walletHdPath,
@@ -61,6 +63,52 @@ const signTransaction = async config => {
61 gasPrice = toHex(toWei(gasPrice, 'gwei'))
63 gasPrice = toHex(toWei(gasPrice, 'gwei'))
62 gasLimit = toHex(gasLimit)
64 gasLimit = toHex(gasLimit)
66+ const txParams = { nonce, chainId, gasPrice, gasLimit }
70+ // Ledger does not seem to handle EIP-155 automatically. When using a Ledger,
71+ // if the block number is at least FORK_BLKNUM = 2675000, one needs to
72+ // pre-set the ECDSA signature parameters with r = 0, s = 0, and v = chainId
75+ // The easiest way to handle this is to just branch on the network, since
76+ // mainnet and Ropsten have obviously passed FORK_BLKNUM. This is somewhat
77+ // awkward when dealing with offline transactions, since we might want to
78+ // test them on a local network as well.
80+ // The best thing to do is probably to add an 'advanced' tab to offline
81+ // transaction generation where one can disable the defaulted-on EIP-155
82+ // settings in this case. This is pretty low-priority, but is a
83+ // comprehensive solution.
87+ // See https://github.com/LedgerHQ/ledgerjs/issues/43#issuecomment-366984725
89+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
91+ const eip155Params = {
97+ const defaultEip155Networks = [
98+ NETWORK_NAMES.MAINNET,
99+ NETWORK_NAMES.ROPSTEN,
100+ NETWORK_NAMES.OFFLINE
103+ const needEip155Params =
104+ walletType === WALLET_NAMES.LEDGER &&
105+ defaultEip155Networks.includes(networkType)
107+ const signingParams =
109+ ? Object.assign(txParams, eip155Params)
64 const wal = wallet.matchWith({
112 const wal = wallet.matchWith({
65 Just: (w) => w.value,
113 Just: (w) => w.value,
66 Nothing: () => { throw BRIDGE_ERROR.MISSING_WALLET }
114 Nothing: () => { throw BRIDGE_ERROR.MISSING_WALLET }
@@ -70,7 +118,7 @@ const signTransaction = async config => {
71 const utx = txn.matchWith({
119 const utx = txn.matchWith({
72 Just: (tx) =>
120 Just: (tx) =>
73− Object.assign(tx.value, { nonce, chainId, gasPrice, gasLimit }),
121+ Object.assign(tx.value, signingParams),
74 Nothing: () => {
122 Nothing: () => {
75 throw BRIDGE_ERROR.MISSING_TXN
123 throw BRIDGE_ERROR.MISSING_TXN