Skip to content

Commit 71aad45

Browse files
committed
Merge remote-tracking branch 'benma/selfsend'
2 parents 8c36506 + 608b92b commit 71aad45

File tree

2 files changed

+50
-38
lines changed

2 files changed

+50
-38
lines changed

backend/coins/btc/transaction.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func (account *Account) newTx(args *accounts.TxProposalArgs) (
213213
return utxo, txProposal, nil
214214
}
215215

216-
// getAddress returns the address in the account with the given `scriptHashHex`. Panics if the
216+
// getAddress returns the address in the account with the given `scriptHashHex`. Returns nil if the
217217
// address does not exist in the account.
218218
func (account *Account) getAddress(scriptHashHex blockchain.ScriptHashHex) *addresses.AccountAddress {
219219
for _, subacc := range account.subaccounts {
@@ -224,7 +224,7 @@ func (account *Account) getAddress(scriptHashHex blockchain.ScriptHashHex) *addr
224224
return address
225225
}
226226
}
227-
panic("address must be present")
227+
return nil
228228
}
229229

230230
// SendTx implements accounts.Interface.

backend/devices/bitbox02/keystore.go

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/btcsuite/btcd/btcutil/hdkeychain"
2525
"github.com/btcsuite/btcd/chaincfg"
2626
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc"
27+
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/blockchain"
2728
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/types"
2829
"github.com/digitalbitbox/bitbox-wallet-app/backend/coins/btc/util"
2930
coinpkg "github.com/digitalbitbox/bitbox-wallet-app/backend/coins/coin"
@@ -343,38 +344,6 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
343344
}
344345
}
345346

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-
}
378347
outputs := make([]*messages.BTCSignOutputRequest, len(tx.TxOut))
379348
for index, txOut := range tx.TxOut {
380349
address, err := util.AddressFromPkScript(txOut.PkScript, coin.Net())
@@ -396,16 +365,26 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
396365
default:
397366
return errp.Newf("unsupported output type: %v", address)
398367
}
368+
outputAddress := btcProposedTx.GetAddress(blockchain.NewScriptHashHex(txOut.PkScript))
369+
399370
changeAddress := btcProposedTx.TXProposal.ChangeAddress
371+
// Could also determine change using `outputAddress != nil AND second-to-last keypath element of outputAddress is 1`.
400372
isChange := changeAddress != nil && bytes.Equal(
401373
changeAddress.PubkeyScript(),
402374
txOut.PkScript,
403375
)
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+
404383
var keypath []uint32
405384
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
409388
msgScriptType, ok := btcMsgScriptTypeMap[accountConfiguration.ScriptType()]
410389
if !ok {
411390
return errp.Newf("Unsupported script type %s", accountConfiguration.ScriptType())
@@ -417,7 +396,7 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
417396

418397
}
419398
outputs[index] = &messages.BTCSignOutputRequest{
420-
Ours: isChange,
399+
Ours: isOurs,
421400
Type: msgOutputType,
422401
Value: uint64(txOut.Value),
423402
Payload: address.ScriptAddress(),
@@ -426,6 +405,39 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
426405
}
427406
}
428407

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+
429441
formatUnit := messages.BTCSignInitRequest_DEFAULT
430442
if btcProposedTx.FormatUnit == coinpkg.BtcUnitSats {
431443
formatUnit = messages.BTCSignInitRequest_SAT

0 commit comments

Comments
 (0)