@@ -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 {
@@ -12,7 +13,6 @@ import {
1213 addHexPrefix
1314 } from '../lib/wallet'
1415
15−
1616const TXN_PURPOSE = {
1717 SET_MANAGEMENT_PROXY: Symbol('SET_MANAGEMENT_PROXY'),
1818 SET_TRANSFER_PROXY: Symbol('SET_TRANSFER_PROXY'),
@@ -43,41 +43,13 @@ const renderTxnPurpose = (purpose) =>
4343 ? 'cancel this transfer'
4444 : 'perform this transaction'
4545
46−
47−
48−
49−
50−// const createUnsignedTxn = config => {
51−// const {
52−// contracts,
53−// galaxyName,
54−// add,
55−// setTxn
56−// } = config
57−//
58−// const ctrcs = contracts.matchWith({
59−// Just: (cs) => cs.value,
60−// Nothing: () => {
61−// throw BRIDGE_ERROR.MISSING_CONTRACTS
62−// }
63−// })
64−//
65−// const galaxy = parseInt(ob.patp2dec(galaxyName), 10)
66−//
67−// const txn = isValidGalaxy(galaxyName) && isValidAddress(galaxyOwner)
68−// ? Maybe.Just(azimuth.ecliptic.createGalaxy(ctrcs, galaxy, galaxyOwner))
69−// : Maybe.Nothing()
70−//
71−// setTxn(txn)
72−// }
73−
74−
7546const signTransaction = async config => {
7647
7748 let {
7849 wallet,
7950 walletType,
8051 walletHdPath,
52+ networkType,
8153 txn,
8254 setStx,
8355 nonce,
@@ -91,18 +63,62 @@ const signTransaction = async config => {
9163 gasPrice = toHex(toWei(gasPrice, 'gwei'))
9264 gasLimit = toHex(gasLimit)
9365
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+
94112 const wal = wallet.matchWith({
95113 Just: (w) => w.value,
96− Nothing: () => {
97− throw BRIDGE_ERROR.MISSING_WALLET
98− }
114+ Nothing: () => { throw BRIDGE_ERROR.MISSING_WALLET }
99115 })
100116
101117 const sec = wal.privateKey
102118
103119 const utx = txn.matchWith({
104120 Just: (tx) =>
105− Object.assign(tx.value, { nonce, chainId, gasPrice, gasLimit }),
121+ Object.assign(tx.value, signingParams),
106122 Nothing: () => {
107123 throw BRIDGE_ERROR.MISSING_TXN
108124 }
@@ -121,8 +137,6 @@ const signTransaction = async config => {
121137 setStx(Maybe.Just(stx))
122138}
123139
124−
125−
126140const sendSignedTransaction = (web3, stx) => {
127141 const txn = stx.matchWith({
128142 Just: (tx) => tx.value,
@@ -170,28 +184,6 @@ const toHex = dummy.utils.toHex
170184const toWei = dummy.utils.toWei
171185const fromWei = dummy.utils.fromWei
172186
173−
174−// const confirmShipAvailability = (point, contracts) => {
175−//
176−// if (canDecodePatp(point) === true) {
177−//
178−// const pointDec = ob.patp2dec(point)
179−//
180−// contracts.matchWith({
181−// Nothing: () => {
182−// throw BRIDGE_ERROR.MISSING_CONTRACTS
183−// },
184−// Just: async (contracts) => {
185−// const owner = await azimuth.azimuth.getOwner(contracts.value, point)
186−// if (eqAddr(owner, ETH_ZERO_ADDR)) return true
187−// return false
188−// }
189−// })
190−// }
191−// return false
192−// }
193−
194−
195187const canDecodePatp = p => {
196188 try {
197189 ob.patp2dec(p)
@@ -201,21 +193,6 @@ const canDecodePatp = p => {
201193 }
202194}
203195
204−
205−
206−
207−
208−// const bridgeAPI = {
209−// shipAvailability: {
210−// planet: planet => {},
211−// star: star => {},
212−// galaxy: galaxy => {},
213−// },
214−// // dummyWeb3: {
215−// //
216−// // }
217−// }
218−
219196export {
220197 signTransaction,
221198 sendSignedTransaction,
@@ -228,5 +205,4 @@ export {
228205 toWei,
229206 fromWei,
230207 canDecodePatp,
231− // confirmShipAvailability,
232208}