@@ -14,7 +14,10 @@ const utxoNetworks = {
14
14
zec : utxoLib . networks . zcash ,
15
15
dash : utxoLib . networks . dash ,
16
16
tltc : utxoLib . networks . litecoin ,
17
- tbtc : utxoLib . networks . testnet
17
+ tbtc : utxoLib . networks . testnet ,
18
+ tbch : utxoLib . networks . bitcoincashTestnet ,
19
+ tzec : utxoLib . networks . zcashTest ,
20
+ tdash : utxoLib . networks . dashTest ,
18
21
} ;
19
22
20
23
const coinDecimals = {
@@ -30,7 +33,10 @@ const coinDecimals = {
30
33
teth : 18 ,
31
34
txrp : 6 ,
32
35
tltc : 8 ,
33
- txlm : 7
36
+ txlm : 7 ,
37
+ tbch : 8 ,
38
+ tzec : 8 ,
39
+ tdash : 8 ,
34
40
} ;
35
41
36
42
const TEN = new BN ( 10 ) ;
@@ -60,7 +66,7 @@ const getHDNodeAndVerify = function(xprv, expectedXpub) {
60
66
let node ;
61
67
62
68
try {
63
- node = prova . HDNode . fromBase58 ( xprv ) ;
69
+ node = utxoLib . HDNode . fromBase58 ( xprv ) ;
64
70
} catch ( e ) {
65
71
throw new Error ( 'invalid private key' ) ;
66
72
}
@@ -103,36 +109,49 @@ const handleSignUtxo = function(recoveryRequest, key, skipConfirm) {
103
109
// force override network as we use btc mainnet xpubs for all utxo coins
104
110
backupKeyNode . keyPair . network = network ;
105
111
112
+ transaction . ins . forEach ( function ( input , i ) {
113
+ transaction . ins [ i ] . value = recoveryRequest . inputs [ i ] . amount ;
114
+ } )
115
+
106
116
const txBuilder = utxoLib . TransactionBuilder . fromTransaction ( transaction , network ) ;
107
117
108
118
_ . forEach ( recoveryRequest . inputs , function ( input , i ) {
109
- const isBech32 = ! input . redeemScript ;
110
- const isSegwit = ! ! input . witnessScript ;
111
119
112
- // chain paths come from the SDK with a leading /, which is technically not allowed by BIP32
120
+ // Set up chain path: chain paths come from the SDK with a leading /, which is technically not allowed by BIP32
113
121
if ( input . chainPath . startsWith ( '/' ) ) {
114
122
input . chainPath = input . chainPath . slice ( 1 ) ;
115
123
}
116
124
125
+ // Derive signing key from chain path
117
126
const derivedHDNode = backupKeyNode . derivePath ( input . chainPath ) ;
118
-
119
127
console . log ( `Signing input ${ i + 1 } of ${ recoveryRequest . inputs . length } with ${ derivedHDNode . neutered ( ) . toBase58 ( ) } (${ input . chainPath } )` ) ;
120
128
121
- if ( isBech32 ) {
129
+ // Handle BCH
130
+ if ( recoveryRequest . coin === 'bch' || recoveryRequest . coin === 'tbch' ) {
131
+ const redeemScript = new Buffer ( input . redeemScript , 'hex' ) ;
132
+ txBuilder . sign ( i , derivedHDNode . keyPair , redeemScript , utxoLib . Transaction . SIGHASH_BITCOINCASHBIP143 | utxoLib . Transaction . SIGHASH_ALL , input . amount ) ;
133
+ return ; // in a Lodash forEach loop, 'return' operates like 'continue' does in a regular javascript loop. It finishes this iteration and moves to the next iteration
134
+ }
135
+
136
+ // Handle Bech32
137
+ if ( ! input . redeemScript ) {
122
138
const witnessScript = Buffer . from ( input . witnessScript , 'hex' ) ;
123
139
const witnessScriptHash = utxoLib . crypto . sha256 ( witnessScript ) ;
124
140
const prevOutScript = utxoLib . script . witnessScriptHash . output . encode ( witnessScriptHash ) ;
125
141
txBuilder . sign ( i , derivedHDNode . keyPair , prevOutScript , utxoLib . Transaction . SIGHASH_ALL , input . amount , witnessScript ) ;
126
- } else {
127
- const redeemScript = new Buffer ( input . redeemScript , 'hex' ) ;
142
+ return ;
143
+ }
128
144
129
- if ( isSegwit ) {
130
- const witnessScript = new Buffer ( input . witnessScript , 'hex' ) ;
131
- txBuilder . sign ( i , derivedHDNode . keyPair , redeemScript , utxoLib . Transaction . SIGHASH_ALL , input . amount , witnessScript )
132
- } else {
133
- txBuilder . sign ( i , derivedHDNode . keyPair , redeemScript , utxoLib . Transaction . SIGHASH_ALL ) ;
134
- }
145
+ // Handle Wrapped Segwit
146
+ const redeemScript = new Buffer ( input . redeemScript , 'hex' ) ;
147
+ if ( input . witnessScript ) {
148
+ const witnessScript = new Buffer ( input . witnessScript , 'hex' ) ;
149
+ txBuilder . sign ( i , derivedHDNode . keyPair , redeemScript , utxoLib . Transaction . SIGHASH_ALL , input . amount , witnessScript ) ;
150
+ return ;
135
151
}
152
+
153
+ // Handle all other requests
154
+ txBuilder . sign ( i , derivedHDNode . keyPair , redeemScript , utxoLib . Transaction . SIGHASH_ALL , input . amount ) ;
136
155
} ) ;
137
156
138
157
return txBuilder . build ( ) . toHex ( ) ;
@@ -160,7 +179,7 @@ const handleSignEthereum = function(recoveryRequest, key, skipConfirm) {
160
179
161
180
const backupKeyNode = getHDNodeAndVerify ( key , recoveryRequest . backupKey ) ;
162
181
163
- const backupSigningKey = backupKeyNode . getKey ( ) . getPrivateKeyBuffer ( ) ;
182
+ const backupSigningKey = backupKeyNode . keyPair . getPrivateKeyBuffer ( ) ;
164
183
165
184
transaction . sign ( backupSigningKey ) ;
166
185
0 commit comments