@@ -359,6 +359,21 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
359
359
360
360
txChangeAddress := btcProposedTx .TXProposal .ChangeAddress
361
361
362
+ // outputScriptConfigs represent the script configurations of a specific account and include the
363
+ // script type (e.g. p2wpkh, p2tr..) and the account keypath
364
+ outputScriptConfigs := []* messages.BTCScriptConfigWithKeypath {}
365
+ // addOutputScriptConfig returns the index of the scriptConfig in outputScriptConfigs, adding it if it isn't
366
+ // present. Must be a Simple configuration.
367
+ addOutputScriptConfig := func (scriptConfig * messages.BTCScriptConfigWithKeypath ) uint32 {
368
+ for i , sc := range outputScriptConfigs {
369
+ if sc .ScriptConfig .Config .(* messages.BTCScriptConfig_SimpleType_ ).SimpleType == scriptConfig .ScriptConfig .Config .(* messages.BTCScriptConfig_SimpleType_ ).SimpleType {
370
+ return uint32 (i )
371
+ }
372
+ }
373
+ outputScriptConfigs = append (outputScriptConfigs , scriptConfig )
374
+ return uint32 (len (outputScriptConfigs ) - 1 )
375
+ }
376
+
362
377
// iterate over tx outputs to add the related scriptconfigs, flag internal addresses and build
363
378
// the output signing requests.
364
379
outputs := make ([]* messages.BTCSignOutputRequest , len (tx .TxOut ))
@@ -399,38 +414,56 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
399
414
txOut .PkScript ,
400
415
)
401
416
402
- // outputAccountAddress represents the same address as outputAddress, but embeds the account configuration.
417
+ // outputAddress represents the same address as outputAddress, but embeds the account configuration.
403
418
// It is nil if the address is external.
404
- outputAccountAddress := btcProposedTx .GetAccountAddress (blockchain .NewScriptHashHex (txOut .PkScript ))
419
+ outputAddress , sameAccount , err := btcProposedTx .GetKeystoreAddress (btcProposedTx .SendingAccount , blockchain .NewScriptHashHex (txOut .PkScript ))
420
+ if err != nil {
421
+ return errp .Newf ("failed to get address: %v" , err )
422
+ }
405
423
406
- isOurs := outputAccountAddress != nil
424
+ isOurs := outputAddress != nil
407
425
if ! isChange && ! keystore .device .Version ().AtLeast (semver .NewSemVer (9 , 15 , 0 )) {
408
426
// For firmware older than 9.15.0, non-change outputs cannot be marked internal.
409
427
isOurs = false
410
428
}
411
429
412
430
var keypath []uint32
413
431
var scriptConfigIndex int
432
+ var outputScriptConfigIndex * uint32
414
433
if isOurs {
415
- keypath = outputAccountAddress .Configuration .AbsoluteKeypath ().ToUInt32 ()
416
- accountConfiguration := outputAccountAddress .AccountConfiguration
434
+ accountConfiguration := outputAddress .AccountConfiguration
417
435
msgScriptType , ok := btcMsgScriptTypeMap [accountConfiguration .ScriptType ()]
418
436
if ! ok {
419
437
return errp .Newf ("Unsupported script type %s" , accountConfiguration .ScriptType ())
420
438
}
421
- scriptConfigIndex = addScriptConfig (& messages.BTCScriptConfigWithKeypath {
422
- ScriptConfig : firmware .NewBTCScriptConfigSimple (msgScriptType ),
423
- Keypath : accountConfiguration .AbsoluteKeypath ().ToUInt32 (),
424
- })
439
+ switch {
440
+ case sameAccount :
441
+ keypath = outputAddress .Configuration .AbsoluteKeypath ().ToUInt32 ()
442
+ scriptConfigIndex = addScriptConfig (& messages.BTCScriptConfigWithKeypath {
443
+ ScriptConfig : firmware .NewBTCScriptConfigSimple (msgScriptType ),
444
+ Keypath : accountConfiguration .AbsoluteKeypath ().ToUInt32 (),
445
+ })
446
+ case keystore .device .Version ().AtLeast (semver .NewSemVer (9 , 22 , 0 )):
447
+ keypath = outputAddress .Configuration .AbsoluteKeypath ().ToUInt32 ()
448
+ outputScriptConfigIdx := addOutputScriptConfig (& messages.BTCScriptConfigWithKeypath {
449
+ ScriptConfig : firmware .NewBTCScriptConfigSimple (msgScriptType ),
450
+ Keypath : accountConfiguration .AbsoluteKeypath ().ToUInt32 (),
451
+ })
452
+ outputScriptConfigIndex = & outputScriptConfigIdx
453
+ default :
454
+ isOurs = false
455
+ }
425
456
}
457
+
426
458
outputs [index ] = & messages.BTCSignOutputRequest {
427
- Ours : isOurs ,
428
- Type : msgOutputType ,
429
- Value : uint64 (txOut .Value ),
430
- Payload : payload ,
431
- Keypath : keypath ,
432
- ScriptConfigIndex : uint32 (scriptConfigIndex ),
433
- SilentPayment : silentPayment ,
459
+ Ours : isOurs ,
460
+ Type : msgOutputType ,
461
+ Value : uint64 (txOut .Value ),
462
+ Payload : payload ,
463
+ Keypath : keypath ,
464
+ ScriptConfigIndex : uint32 (scriptConfigIndex ),
465
+ SilentPayment : silentPayment ,
466
+ OutputScriptConfigIndex : outputScriptConfigIndex ,
434
467
}
435
468
}
436
469
@@ -489,6 +522,7 @@ func (keystore *keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
489
522
signatures , generatedOutputs , err := keystore .device .BTCSign (
490
523
msgCoin ,
491
524
scriptConfigs ,
525
+ outputScriptConfigs ,
492
526
& firmware.BTCTx {
493
527
Version : uint32 (tx .Version ),
494
528
Inputs : inputs ,
0 commit comments