@@ -24,6 +24,7 @@ import (
24
24
"github.com/btcsuite/btcd/btcutil/hdkeychain"
25
25
"github.com/btcsuite/btcd/chaincfg"
26
26
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc"
27
+ "github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/blockchain"
27
28
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/types"
28
29
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/util"
29
30
coinpkg "github.com/digitalbitbox/bitbox-wallet-app/backend/coins/coin"
@@ -343,38 +344,6 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
343
344
}
344
345
}
345
346
346
- // Provide the previous transaction for each input if needed.
347
- if firmware .BTCSignNeedsPrevTxs (scriptConfigs ) {
348
- for inputIndex , txIn := range tx .TxIn {
349
- prevTx , err := btcProposedTx .GetPrevTx (txIn .PreviousOutPoint .Hash )
350
- if err != nil {
351
- return err
352
- }
353
-
354
- prevTxInputs := make ([]* messages.BTCPrevTxInputRequest , len (prevTx .TxIn ))
355
- for prevInputIndex , prevTxIn := range prevTx .TxIn {
356
- prevTxInputs [prevInputIndex ] = & messages.BTCPrevTxInputRequest {
357
- PrevOutHash : prevTxIn .PreviousOutPoint .Hash [:],
358
- PrevOutIndex : prevTxIn .PreviousOutPoint .Index ,
359
- SignatureScript : prevTxIn .SignatureScript ,
360
- Sequence : prevTxIn .Sequence ,
361
- }
362
- }
363
- prevTxOuputs := make ([]* messages.BTCPrevTxOutputRequest , len (prevTx .TxOut ))
364
- for prevOutputIndex , prevTxOut := range prevTx .TxOut {
365
- prevTxOuputs [prevOutputIndex ] = & messages.BTCPrevTxOutputRequest {
366
- Value : uint64 (prevTxOut .Value ),
367
- PubkeyScript : prevTxOut .PkScript ,
368
- }
369
- }
370
- inputs [inputIndex ].PrevTx = & firmware.BTCPrevTx {
371
- Version : uint32 (prevTx .Version ),
372
- Inputs : prevTxInputs ,
373
- Outputs : prevTxOuputs ,
374
- Locktime : prevTx .LockTime ,
375
- }
376
- }
377
- }
378
347
outputs := make ([]* messages.BTCSignOutputRequest , len (tx .TxOut ))
379
348
for index , txOut := range tx .TxOut {
380
349
address , err := util .AddressFromPkScript (txOut .PkScript , coin .Net ())
@@ -396,16 +365,26 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
396
365
default :
397
366
return errp .Newf ("unsupported output type: %v" , address )
398
367
}
368
+ outputAddress := btcProposedTx .GetAddress (blockchain .NewScriptHashHex (txOut .PkScript ))
369
+
399
370
changeAddress := btcProposedTx .TXProposal .ChangeAddress
371
+ // Could also determine change using `outputAddress != nil AND second-to-last keypath element of outputAddress is 1`.
400
372
isChange := changeAddress != nil && bytes .Equal (
401
373
changeAddress .PubkeyScript (),
402
374
txOut .PkScript ,
403
375
)
376
+
377
+ isOurs := outputAddress != nil
378
+ if ! isChange && ! keystore .device .Version ().AtLeast (semver .NewSemVer (9 , 15 , 0 )) {
379
+ // For firmware older than 9.15.0, non-change outputs cannot be marked internal.
380
+ isOurs = false
381
+ }
382
+
404
383
var keypath []uint32
405
384
var scriptConfigIndex int
406
- if isChange {
407
- keypath = changeAddress .Configuration .AbsoluteKeypath ().ToUInt32 ()
408
- accountConfiguration := changeAddress .AccountConfiguration
385
+ if isOurs {
386
+ keypath = outputAddress .Configuration .AbsoluteKeypath ().ToUInt32 ()
387
+ accountConfiguration := outputAddress .AccountConfiguration
409
388
msgScriptType , ok := btcMsgScriptTypeMap [accountConfiguration .ScriptType ()]
410
389
if ! ok {
411
390
return errp .Newf ("Unsupported script type %s" , accountConfiguration .ScriptType ())
@@ -417,7 +396,7 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
417
396
418
397
}
419
398
outputs [index ] = & messages.BTCSignOutputRequest {
420
- Ours : isChange ,
399
+ Ours : isOurs ,
421
400
Type : msgOutputType ,
422
401
Value : uint64 (txOut .Value ),
423
402
Payload : address .ScriptAddress (),
@@ -426,6 +405,39 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
426
405
}
427
406
}
428
407
408
+ // Provide the previous transaction for each input if needed.
409
+ if firmware .BTCSignNeedsPrevTxs (scriptConfigs ) {
410
+ for inputIndex , txIn := range tx .TxIn {
411
+ prevTx , err := btcProposedTx .GetPrevTx (txIn .PreviousOutPoint .Hash )
412
+ if err != nil {
413
+ return err
414
+ }
415
+
416
+ prevTxInputs := make ([]* messages.BTCPrevTxInputRequest , len (prevTx .TxIn ))
417
+ for prevInputIndex , prevTxIn := range prevTx .TxIn {
418
+ prevTxInputs [prevInputIndex ] = & messages.BTCPrevTxInputRequest {
419
+ PrevOutHash : prevTxIn .PreviousOutPoint .Hash [:],
420
+ PrevOutIndex : prevTxIn .PreviousOutPoint .Index ,
421
+ SignatureScript : prevTxIn .SignatureScript ,
422
+ Sequence : prevTxIn .Sequence ,
423
+ }
424
+ }
425
+ prevTxOuputs := make ([]* messages.BTCPrevTxOutputRequest , len (prevTx .TxOut ))
426
+ for prevOutputIndex , prevTxOut := range prevTx .TxOut {
427
+ prevTxOuputs [prevOutputIndex ] = & messages.BTCPrevTxOutputRequest {
428
+ Value : uint64 (prevTxOut .Value ),
429
+ PubkeyScript : prevTxOut .PkScript ,
430
+ }
431
+ }
432
+ inputs [inputIndex ].PrevTx = & firmware.BTCPrevTx {
433
+ Version : uint32 (prevTx .Version ),
434
+ Inputs : prevTxInputs ,
435
+ Outputs : prevTxOuputs ,
436
+ Locktime : prevTx .LockTime ,
437
+ }
438
+ }
439
+ }
440
+
429
441
formatUnit := messages .BTCSignInitRequest_DEFAULT
430
442
if btcProposedTx .FormatUnit == coinpkg .BtcUnitSats {
431
443
formatUnit = messages .BTCSignInitRequest_SAT
0 commit comments