@@ -5,6 +5,7 @@ import Tx from 'ethereumjs-tx'
55import Web3 from 'web3'
66
77import { BRIDGE_ERROR } from '../lib/error'
8+import { NETWORK_NAMES } from '../lib/network'
89import { ledgerSignTransaction } from '../lib/ledger'
910import { trezorSignTransaction } from '../lib/trezor'
1011import {
@@ -48,6 +49,7 @@ const signTransaction = async config => {
4849 wallet,
4950 walletType,
5051 walletHdPath,
52+ networkType,
5153 txn,
5254 setStx,
5355 nonce,
@@ -61,6 +63,52 @@ const signTransaction = async config => {
6163 gasPrice = toHex(toWei(gasPrice, 'gwei'))
6264 gasLimit = toHex(gasLimit)
6365
66+ const txParams = { nonce, chainId, gasPrice, gasLimit }
67+
68+ // NB (jtobin)
69+ //
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
73+ // prior to signing.
74+ //
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.
79+ //
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.
84+ //
85+ // See:
86+ //
87+ // See https://github.com/LedgerHQ/ledgerjs/issues/43#issuecomment-366984725
88+ //
89+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
90+
91+ const eip155Params = {
92+ r: '0x00',
93+ s: '0x00',
94+ v: chainId
95+ }
96+
97+ const defaultEip155Networks = [
98+ NETWORK_NAMES.MAINNET,
99+ NETWORK_NAMES.ROPSTEN,
100+ NETWORK_NAMES.OFFLINE
101+ ]
102+
103+ const needEip155Params =
104+ walletType === WALLET_NAMES.LEDGER &&
105+ defaultEip155Networks.includes(networkType)
106+
107+ const signingParams =
108+ needEip155Params
109+ ? Object.assign(txParams, eip155Params)
110+ : txParams
111+
64112 const wal = wallet.matchWith({
65113 Just: (w) => w.value,
66114 Nothing: () => { throw BRIDGE_ERROR.MISSING_WALLET }
@@ -70,7 +118,7 @@ const signTransaction = async config => {
70118
71119 const utx = txn.matchWith({
72120 Just: (tx) =>
73− Object.assign(tx.value, { nonce, chainId, gasPrice, gasLimit }),
121+ Object.assign(tx.value, signingParams),
74122 Nothing: () => {
75123 throw BRIDGE_ERROR.MISSING_TXN
76124 }