@@ -78,6 +78,12 @@ const confirmRecovery = function(backupKey, outputs, customMessage, skipConfirm)
78
78
}
79
79
} ;
80
80
81
+ /**
82
+ * Verifies that input is a valid HD key and parses it into HDNode object.
83
+ * @param xprv Base58 representation of extended private key
84
+ * @param expectedXpub The corresponding extended public key
85
+ * @returns The HDNode object representing the extended private key
86
+ */
81
87
const getHDNodeAndVerify = function ( xprv , expectedXpub ) {
82
88
let node ;
83
89
@@ -99,7 +105,7 @@ const getHDNodeAndVerify = function(xprv, expectedXpub) {
99
105
} ;
100
106
101
107
/**
102
- * Prints the recovery transaction information and prompt for the confirmation as well as the key, if needed to.
108
+ * Prints the recovery transaction information and prompt the user for the confirmation as well as the key, if needed to.
103
109
* @param recoveryRequest The recovery transansaction request object.
104
110
* @param outputs The outputs of the transaction.
105
111
* @param skipConfirm The boolean value that indicates to whether or not to prompt the user to confirm the transaction.
@@ -120,14 +126,14 @@ const promptForConfirmationAndKey = function(recoveryRequest, outputs, skipConfi
120
126
121
127
/**
122
128
* Gets the backup private key that can be used to sign the transaction.
123
- * @param key The provided private key.
129
+ * @param xprv The provided extended private key (BIP32) .
124
130
* @param expectedXpub The public key specified with the request.
125
131
* @returns The private key to sign the transaction.
126
132
*/
127
- const getBackupSigningKey = function ( key , expectedXpub ) {
128
- const backupKeyNode = getHDNodeAndVerify ( key , expectedXpub ) ;
133
+ const getBackupSigningKey = function ( xprv , expectedXpub ) {
134
+ const backupKeyNode = getHDNodeAndVerify ( xprv , expectedXpub ) ;
129
135
130
- return backupKeyNode . keyPair . getPrivateKeyBuffer ;
136
+ return backupKeyNode . keyPair . getPrivateKeyBuffer ( ) ;
131
137
}
132
138
133
139
const handleSignUtxo = function ( recoveryRequest , key , skipConfirm ) {
@@ -219,6 +225,7 @@ const handleSignEthereum = function(recoveryRequest, key, skipConfirm) {
219
225
*/
220
226
const signEthTx = function ( recoveryRequest , key , skipConfirm , isToken ) {
221
227
const EthTx = require ( 'ethereumjs-tx' ) ;
228
+ const EthUtil = require ( 'ethereumjs-util' ) ;
222
229
223
230
const txHex = getTransactionHexFromRequest ( recoveryRequest ) ;
224
231
const transaction = new EthTx ( txHex ) ;
@@ -236,9 +243,20 @@ const signEthTx = function(recoveryRequest, key, skipConfirm, isToken) {
236
243
outputs [ 0 ] . amount = outputs [ 0 ] . amount . div ( TEN . pow ( decimals ) ) ;
237
244
}
238
245
239
- key = promptForConfirmationAndKey ( recoveryRequest , outputs , skipConfirm , key ) ;
246
+ // When generating signatures, we don't currently use EIP155 but this could
247
+ // be activated if we wanted to. This would protect against replay attacks on other
248
+ // blockchains, such as Ethereum Classic. To activate the EIP155, we would have to
249
+ // know the chain ID of the Ethereum blockchains we are using as this value goes
250
+ // into the V field when using EIP155.
251
+ // cf. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
252
+ const useEip155 = false ;
240
253
241
- transaction . sign ( getBackupSigningKey ( key , recoveryRequest . backupKey ) ) ;
254
+ key = promptForConfirmationAndKey ( recoveryRequest , outputs , skipConfirm , key ) ;
255
+ const signingKey = Buffer . from ( getBackupSigningKey ( key , recoveryRequest . backupKey ) , "hex" ) ;
256
+ const signature = EthUtil . ecsign ( transaction . hash ( useEip155 ) , signingKey , transaction . chainId ) ;
257
+ transaction . v = signature . v ; // Change this if activating EIP155
258
+ transaction . r = signature . r ;
259
+ transaction . s = signature . s ;
242
260
243
261
return transaction . serialize ( ) . toString ( 'hex' ) ;
244
262
} ;
@@ -258,8 +276,9 @@ const handleSignTrx = function(recoveryRequest, key, skipConfirm) {
258
276
} ) ;
259
277
260
278
key = promptForConfirmationAndKey ( recoveryRequest , outputs , skipConfirm , key ) ;
279
+ const signingKey = getBackupSigningKey ( key , recoveryRequest . backupKey ) ;
261
280
262
- builder . sign ( { key : getBackupSigningKey ( key , recoveryRequest . backupKey ) } ) ;
281
+ builder . sign ( { key : signingKey } ) ;
263
282
return JSON . stringify ( builder . build ( ) . toJson ( ) ) ;
264
283
} ;
265
284
0 commit comments