on master help sign in
Manually follow EIP-155 in certain circumstances.
8184c25Jared Tobin
src/components/StatelessTransaction.js+1
@@ -114,6 +114,7 @@ const StatelessTransaction = props => {
114 wallet: props.wallet,
114 wallet: props.wallet,
115 walletType: props.walletType,
115 walletType: props.walletType,
116 walletHdPath: props.walletHdPath,
116 walletHdPath: props.walletHdPath,
117+ networkType: props.networkType,
117 txn: props.txn,
118 txn: props.txn,
118 setStx: props.setStx,
119 setStx: props.setStx,
119 nonce: props.nonce,
120 nonce: props.nonce,
src/lib/txn.js+49−1
@@ -5,6 +5,7 @@ import Tx from 'ethereumjs-tx'
5import Web3 from 'web3'
5import Web3 from 'web3'
6
6
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'
10import {
11import {
@@ -48,6 +49,7 @@ const signTransaction = async config => {
48 wallet,
49 wallet,
49 walletType,
50 walletType,
50 walletHdPath,
51 walletHdPath,
52+ networkType,
51 txn,
53 txn,
52 setStx,
54 setStx,
53 nonce,
55 nonce,
@@ -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)
63
65
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+
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 => {
70
118
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
76 }
124 }
src/views/AcceptTransfer.js+1
@@ -303,6 +303,7 @@ class AcceptTransfer extends React.Component {
303 wallet={props.wallet}
303 wallet={props.wallet}
304 walletType={props.walletType}
304 walletType={props.walletType}
305 walletHdPath={props.walletHdPath}
305 walletHdPath={props.walletHdPath}
306+ networkType={props.networkType}
306 // Tx
307 // Tx
307 txn={state.txn}
308 txn={state.txn}
308 stx={state.stx}
309 stx={state.stx}
src/views/CancelTransfer.js+1
@@ -234,6 +234,7 @@ class CancelTransfer extends React.Component {
234 wallet={props.wallet}
234 wallet={props.wallet}
235 walletType={props.walletType}
235 walletType={props.walletType}
236 walletHdPath={props.walletHdPath}
236 walletHdPath={props.walletHdPath}
237+ networkType={props.networkType}
237 // Tx
238 // Tx
238 txn={state.txn}
239 txn={state.txn}
239 stx={state.stx}
240 stx={state.stx}
src/views/CreateGalaxy.js+1
@@ -249,6 +249,7 @@ class CreateGalaxy extends React.Component {
249 wallet={props.wallet}
249 wallet={props.wallet}
250 walletType={props.walletType}
250 walletType={props.walletType}
251 walletHdPath={props.walletHdPath}
251 walletHdPath={props.walletHdPath}
252+ networkType={props.networkType}
252 // Tx
253 // Tx
253 txApproval={state.txApproval}
254 txApproval={state.txApproval}
254 txn={state.txn}
255 txn={state.txn}
src/views/IssueChild.js+2
@@ -461,6 +461,7 @@ class IssueChild extends React.Component {
461 wallet={props.wallet}
461 wallet={props.wallet}
462 walletType={props.walletType}
462 walletType={props.walletType}
463 walletHdPath={props.walletHdPath}
463 walletHdPath={props.walletHdPath}
464+ networkType={props.networkType}
464 // Tx
465 // Tx
465 txn={state.txn}
466 txn={state.txn}
466 stx={state.stx}
467 stx={state.stx}
@@ -498,6 +499,7 @@ class IssueChild extends React.Component {
498 { state.txError.value }
499 { state.txError.value }
499 </Warning>
500 </Warning>
500 }
501 }
502+
501 </Col>
503 </Col>
502 </Row>
504 </Row>
503 )
505 )
src/views/SetKeys.js+1
@@ -329,6 +329,7 @@ class SetKeys extends React.Component {
329 contracts={props.contracts}
329 contracts={props.contracts}
330 wallet={props.wallet}
330 wallet={props.wallet}
331 walletType={props.walletType}
331 walletType={props.walletType}
332+ networkType={props.networkType}
332 // Tx
333 // Tx
333 txn={state.txn}
334 txn={state.txn}
334 stx={state.stx}
335 stx={state.stx}
src/views/SetProxy.js+2
@@ -293,6 +293,7 @@ class SetProxy extends React.Component {
293 'Generator to generate a keypair.'
293 'Generator to generate a keypair.'
294 }
294 }
295 </P>
295 </P>
296+
296 <AddressInput
297 <AddressInput
297 className='mono mt-8'
298 className='mono mt-8'
298 prop-size='lg'
299 prop-size='lg'
@@ -320,6 +321,7 @@ class SetProxy extends React.Component {
320 wallet={props.wallet}
321 wallet={props.wallet}
321 walletType={props.walletType}
322 walletType={props.walletType}
322 walletHdPath={props.walletHdPath}
323 walletHdPath={props.walletHdPath}
324+ networkType={props.networkType}
323 // Tx
325 // Tx
324 txn={state.txn}
326 txn={state.txn}
325 stx={state.stx}
327 stx={state.stx}
src/views/Transfer.js+2
@@ -265,6 +265,7 @@ class Transfer extends React.Component {
265 You may cancel the transfer until the transfer is accepted.`
265 You may cancel the transfer until the transfer is accepted.`
266 }
266 }
267 </P>
267 </P>
268+
268 <AddressInput
269 <AddressInput
269 className={'mono mt-8'}
270 className={'mono mt-8'}
270 prop-size='lg'
271 prop-size='lg'
@@ -292,6 +293,7 @@ class Transfer extends React.Component {
292 wallet={props.wallet}
293 wallet={props.wallet}
293 walletType={props.walletType}
294 walletType={props.walletType}
294 walletHdPath={props.walletHdPath}
295 walletHdPath={props.walletHdPath}
296+ networkType={props.networkType}
295 // Tx
297 // Tx
296 txn={state.txn}
298 txn={state.txn}
297 stx={state.stx}
299 stx={state.stx}