@@ -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'
@@ -12,7 +13,6 @@ import {
12 addHexPrefix
13 addHexPrefix
13 } from '../lib/wallet'
14 } from '../lib/wallet'
16const TXN_PURPOSE = {
16const TXN_PURPOSE = {
17 SET_MANAGEMENT_PROXY: Symbol('SET_MANAGEMENT_PROXY'),
17 SET_MANAGEMENT_PROXY: Symbol('SET_MANAGEMENT_PROXY'),
18 SET_TRANSFER_PROXY: Symbol('SET_TRANSFER_PROXY'),
18 SET_TRANSFER_PROXY: Symbol('SET_TRANSFER_PROXY'),
@@ -43,41 +43,13 @@ const renderTxnPurpose = (purpose) =>
43 ? 'cancel this transfer'
43 ? 'cancel this transfer'
44 : 'perform this transaction'
44 : 'perform this transaction'
50−// const createUnsignedTxn = config => {
58−// const ctrcs = contracts.matchWith({
59−// Just: (cs) => cs.value,
61−// throw BRIDGE_ERROR.MISSING_CONTRACTS
65−// const galaxy = parseInt(ob.patp2dec(galaxyName), 10)
67−// const txn = isValidGalaxy(galaxyName) && isValidAddress(galaxyOwner)
68−// ? Maybe.Just(azimuth.ecliptic.createGalaxy(ctrcs, galaxy, galaxyOwner))
75const signTransaction = async config => {
46const signTransaction = async config => {
79 walletType,
50 walletType,
80 walletHdPath,
51 walletHdPath,
@@ -91,18 +63,62 @@ const signTransaction = async config => {
91 gasPrice = toHex(toWei(gasPrice, 'gwei'))
63 gasPrice = toHex(toWei(gasPrice, 'gwei'))
92 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)
94 const wal = wallet.matchWith({
112 const wal = wallet.matchWith({
95 Just: (w) => w.value,
113 Just: (w) => w.value,
97− throw BRIDGE_ERROR.MISSING_WALLET
114+ Nothing: () => { throw BRIDGE_ERROR.MISSING_WALLET }
101 const sec = wal.privateKey
117 const sec = wal.privateKey
103 const utx = txn.matchWith({
119 const utx = txn.matchWith({
104 Just: (tx) =>
120 Just: (tx) =>
105− Object.assign(tx.value, { nonce, chainId, gasPrice, gasLimit }),
121+ Object.assign(tx.value, signingParams),
106 Nothing: () => {
122 Nothing: () => {
107 throw BRIDGE_ERROR.MISSING_TXN
123 throw BRIDGE_ERROR.MISSING_TXN
@@ -121,8 +137,6 @@ const signTransaction = async config => {
121 setStx(Maybe.Just(stx))
137 setStx(Maybe.Just(stx))
126const sendSignedTransaction = (web3, stx) => {
140const sendSignedTransaction = (web3, stx) => {
127 const txn = stx.matchWith({
141 const txn = stx.matchWith({
128 Just: (tx) => tx.value,
142 Just: (tx) => tx.value,
@@ -170,28 +184,6 @@ const toHex = dummy.utils.toHex
170const toWei = dummy.utils.toWei
184const toWei = dummy.utils.toWei
171const fromWei = dummy.utils.fromWei
185const fromWei = dummy.utils.fromWei
174−// const confirmShipAvailability = (point, contracts) => {
176−// if (canDecodePatp(point) === true) {
178−// const pointDec = ob.patp2dec(point)
180−// contracts.matchWith({
182−// throw BRIDGE_ERROR.MISSING_CONTRACTS
184−// Just: async (contracts) => {
185−// const owner = await azimuth.azimuth.getOwner(contracts.value, point)
186−// if (eqAddr(owner, ETH_ZERO_ADDR)) return true
195const canDecodePatp = p => {
187const canDecodePatp = p => {
197 ob.patp2dec(p)
189 ob.patp2dec(p)
@@ -201,21 +193,6 @@ const canDecodePatp = p => {
208−// const bridgeAPI = {
209−// shipAvailability: {
210−// planet: planet => {},
212−// galaxy: galaxy => {},
220 signTransaction,
197 signTransaction,
221 sendSignedTransaction,
198 sendSignedTransaction,
@@ -228,5 +205,4 @@ export {
230 canDecodePatp,
207 canDecodePatp,
231− // confirmShipAvailability,