1
1
const Promise = require ( 'bluebird' ) ;
2
2
const co = Promise . coroutine ;
3
- const utxoLib = require ( 'bitgo-utxo-lib' ) ;
3
+ const bip32 = require ( 'bip32' ) ;
4
+ const utxolib = require ( '@bitgo/utxo-lib' ) ;
4
5
const accountLib = require ( '@bitgo/account-lib' ) ;
5
6
const statics = require ( '@bitgo/statics' ) ;
6
7
const fs = require ( 'fs' ) ;
@@ -14,18 +15,18 @@ const bitgojs = require('bitgo');
14
15
let bitgo ;
15
16
16
17
const utxoNetworks = {
17
- btc : utxoLib . networks . bitcoin ,
18
- ltc : utxoLib . networks . litecoin ,
19
- bch : utxoLib . networks . bitcoincash ,
20
- bsv : utxoLib . networks . bitcoinsv ,
21
- zec : utxoLib . networks . zcash ,
22
- dash : utxoLib . networks . dash ,
23
- tltc : utxoLib . networks . litecoin ,
24
- tbtc : utxoLib . networks . testnet ,
25
- tbch : utxoLib . networks . bitcoincashTestnet ,
26
- tbsv : utxoLib . networks . bitcoinsvTestnet ,
27
- tzec : utxoLib . networks . zcashTest ,
28
- tdash : utxoLib . networks . dashTest
18
+ btc : utxolib . networks . bitcoin ,
19
+ ltc : utxolib . networks . litecoin ,
20
+ bch : utxolib . networks . bitcoincash ,
21
+ bsv : utxolib . networks . bitcoinsv ,
22
+ zec : utxolib . networks . zcash ,
23
+ dash : utxolib . networks . dash ,
24
+ tltc : utxolib . networks . litecoin ,
25
+ tbtc : utxolib . networks . testnet ,
26
+ tbch : utxolib . networks . bitcoincashTestnet ,
27
+ tbsv : utxolib . networks . bitcoinsvTestnet ,
28
+ tzec : utxolib . networks . zcashTest ,
29
+ tdash : utxolib . networks . dashTest
29
30
} ;
30
31
31
32
const coinDecimals = {
@@ -90,7 +91,7 @@ const getHDNodeAndVerify = function(xprv, expectedXpub) {
90
91
let node ;
91
92
92
93
try {
93
- node = utxoLib . HDNode . fromBase58 ( xprv ) ;
94
+ node = bip32 . fromBase58 ( xprv ) ;
94
95
} catch ( e ) {
95
96
throw new Error ( 'invalid private key' ) ;
96
97
}
@@ -131,12 +132,10 @@ const promptForConfirmationAndKey = function(recoveryRequest, outputs, skipConfi
131
132
* Gets the backup private key that can be used to sign the transaction.
132
133
* @param xprv The provided extended private key (BIP32).
133
134
* @param expectedXpub The public key specified with the request.
134
- * @returns The private key to sign the transaction.
135
+ * @returns { Buffer } - the private key buffer to sign the transaction.
135
136
*/
136
137
const getBackupSigningKey = function ( xprv , expectedXpub ) {
137
- const backupKeyNode = getHDNodeAndVerify ( xprv , expectedXpub ) ;
138
-
139
- return backupKeyNode . keyPair . getPrivateKeyBuffer ( ) ;
138
+ return getHDNodeAndVerify ( xprv , expectedXpub ) . privateKey ;
140
139
} ;
141
140
142
141
const handleSignUtxo = function ( recoveryRequest , key , skipConfirm ) {
@@ -148,25 +147,26 @@ const handleSignUtxo = function(recoveryRequest, key, skipConfirm) {
148
147
}
149
148
150
149
const txHex = getTransactionHexFromRequest ( recoveryRequest ) ;
151
- const transaction = utxoLib . Transaction . fromHex ( txHex , network ) ;
150
+ const transaction = utxolib . Transaction . fromHex ( txHex , network ) ;
152
151
153
152
const outputs = transaction . outs . map ( out => ( {
154
- address : utxoLib . address . fromOutputScript ( out . script , network ) ,
153
+ address : utxolib . address . fromOutputScript ( out . script , network ) ,
155
154
amount : ( new BN ( out . value ) ) . div ( TEN . pow ( decimals ) ) . toString ( )
156
155
} ) ) ;
157
156
158
157
key = promptForConfirmationAndKey ( recoveryRequest , outputs , skipConfirm , key ) ;
159
158
160
- const backupKeyNode = getHDNodeAndVerify ( key , recoveryRequest . backupKey ) ;
161
-
162
159
// force override network as we use btc mainnet xpubs for all utxo coins
163
- backupKeyNode . keyPair . network = network ;
160
+ const backupKeyNode = Object . assign (
161
+ getHDNodeAndVerify ( key , recoveryRequest . backupKey ) ,
162
+ { network }
163
+ ) ;
164
164
165
165
transaction . ins . forEach ( function ( input , i ) {
166
166
transaction . ins [ i ] . value = recoveryRequest . inputs [ i ] . amount ;
167
167
} ) ;
168
168
169
- const txBuilder = utxoLib . TransactionBuilder . fromTransaction ( transaction , network ) ;
169
+ const txBuilder = utxolib . TransactionBuilder . fromTransaction ( transaction , network ) ;
170
170
171
171
_ . forEach ( recoveryRequest . inputs , function ( input , i ) {
172
172
@@ -183,8 +183,8 @@ const handleSignUtxo = function(recoveryRequest, key, skipConfirm) {
183
183
// Handle BCH
184
184
if ( BCH_COINS . includes ( recoveryRequest . coin ) ) {
185
185
const redeemScript = new Buffer ( input . redeemScript , 'hex' ) ;
186
- txBuilder . sign ( i , derivedHDNode . keyPair , redeemScript ,
187
- utxoLib . Transaction . SIGHASH_BITCOINCASHBIP143 | utxoLib . Transaction . SIGHASH_ALL , input . amount ) ;
186
+ txBuilder . sign ( i , derivedHDNode , redeemScript ,
187
+ utxolib . Transaction . SIGHASH_BITCOINCASHBIP143 | utxolib . Transaction . SIGHASH_ALL , input . amount ) ;
188
188
// in a Lodash forEach loop, 'return' operates like 'continue' does
189
189
// in a regular javascript loop. It finishes this iteration and moves to the next iteration
190
190
return ;
@@ -193,24 +193,24 @@ const handleSignUtxo = function(recoveryRequest, key, skipConfirm) {
193
193
// Handle Bech32
194
194
if ( ! input . redeemScript ) {
195
195
const witnessScript = Buffer . from ( input . witnessScript , 'hex' ) ;
196
- const witnessScriptHash = utxoLib . crypto . sha256 ( witnessScript ) ;
197
- const prevOutScript = utxoLib . script . witnessScriptHash . output . encode ( witnessScriptHash ) ;
198
- txBuilder . sign ( i , derivedHDNode . keyPair , prevOutScript ,
199
- utxoLib . Transaction . SIGHASH_ALL , input . amount , witnessScript ) ;
196
+ const witnessScriptHash = utxolib . crypto . sha256 ( witnessScript ) ;
197
+ const prevOutScript = utxolib . script . witnessScriptHash . output . encode ( witnessScriptHash ) ;
198
+ txBuilder . sign ( i , derivedHDNode , prevOutScript ,
199
+ utxolib . Transaction . SIGHASH_ALL , input . amount , witnessScript ) ;
200
200
return ;
201
201
}
202
202
203
203
// Handle Wrapped Segwit
204
204
const redeemScript = new Buffer ( input . redeemScript , 'hex' ) ;
205
205
if ( input . witnessScript ) {
206
206
const witnessScript = new Buffer ( input . witnessScript , 'hex' ) ;
207
- txBuilder . sign ( i , derivedHDNode . keyPair , redeemScript ,
208
- utxoLib . Transaction . SIGHASH_ALL , input . amount , witnessScript ) ;
207
+ txBuilder . sign ( i , derivedHDNode , redeemScript ,
208
+ utxolib . Transaction . SIGHASH_ALL , input . amount , witnessScript ) ;
209
209
return ;
210
210
}
211
211
212
212
// Handle all other requests
213
- txBuilder . sign ( i , derivedHDNode . keyPair , redeemScript , utxoLib . Transaction . SIGHASH_ALL , input . amount ) ;
213
+ txBuilder . sign ( i , derivedHDNode , redeemScript , utxolib . Transaction . SIGHASH_ALL , input . amount ) ;
214
214
} ) ;
215
215
216
216
return txBuilder . build ( ) . toHex ( ) ;
@@ -347,8 +347,8 @@ const handleSignXrp = function(recoveryRequest, key, skipConfirm) {
347
347
348
348
const backupKeyNode = getHDNodeAndVerify ( key , recoveryRequest . backupKey ) ;
349
349
350
- const backupAddress = rippleKeypairs . deriveAddress ( backupKeyNode . keyPair . getPublicKeyBuffer ( ) . toString ( 'hex' ) ) ;
351
- const privateKeyHex = backupKeyNode . keyPair . getPrivateKeyBuffer ( ) . toString ( 'hex' ) ;
350
+ const backupAddress = rippleKeypairs . deriveAddress ( backupKeyNode . publicKey . toString ( 'hex' ) ) ;
351
+ const privateKeyHex = backupKeyNode . privateKey . toString ( 'hex' ) ;
352
352
const cosignedTx = utils . signXrpWithPrivateKey ( txHex , privateKeyHex , { signAs : backupAddress } ) ;
353
353
354
354
return rippleApi . combine ( [ txHex , cosignedTx . signedTransaction ] ) . signedTransaction ;
@@ -421,20 +421,18 @@ const parseKey = co(function *(rawkey, coin, path) {
421
421
throw new Error ( 'Invalid mnemonic' ) ;
422
422
}
423
423
const seed = yield bip39 . mnemonicToSeed ( mnemonic ) ;
424
- let node = utxoLib . HDNode . fromSeedBuffer ( seed ) ;
424
+ let node = bip32 . fromSeed ( seed ) ;
425
425
if ( path ) {
426
426
node = node . derivePath ( path ) ;
427
427
}
428
428
const xprv = node . toBase58 ( ) ;
429
429
return xprv ;
430
430
431
431
}
432
- // if it doesn't have commas, we expect it is an xprv or xlmsecret properly formatted
433
432
if ( path ) {
434
- let node = utxoLib . HDNode . fromPrivateKeyBuffer ( Buffer . from ( rawkey , 'hex' ) ) ;
435
- node = node . derivePath ( path ) ;
436
- return node . toBase58 ( ) ;
433
+ throw new Error ( 'can only derive subkey from bip32 xprv' ) ;
437
434
}
435
+ // if it doesn't have commas or a path, return unchanged input
438
436
return rawkey ;
439
437
} ) ;
440
438
0 commit comments