16
16
package firmware
17
17
18
18
import (
19
+ "bytes"
19
20
"errors"
20
21
"testing"
21
22
@@ -36,6 +37,7 @@ import (
36
37
37
38
const hardenedKeyStart = 0x80000000
38
39
40
+ //nolint:unparam
39
41
func mustOutpoint (s string ) * wire.OutPoint {
40
42
outPoint , err := wire .NewOutPointFromString (s )
41
43
if err != nil {
@@ -68,7 +70,7 @@ func TestNewXPub(t *testing.T) {
68
70
}
69
71
70
72
func TestBTCXpub (t * testing.T ) {
71
- testInitializedSimulators (t , func (t * testing.T , device * Device ) {
73
+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes. Buffer ) {
72
74
t .Helper ()
73
75
xpub , err := device .BTCXPub (messages .BTCCoin_TBTC , []uint32 {
74
76
49 + hardenedKeyStart ,
@@ -80,9 +82,10 @@ func TestBTCXpub(t *testing.T) {
80
82
})
81
83
}
82
84
83
- func TestBTCAddress (t * testing.T ) {
84
- testInitializedSimulators (t , func (t * testing.T , device * Device ) {
85
+ func TestSimulatorBTCAddress (t * testing.T ) {
86
+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes. Buffer ) {
85
87
t .Helper ()
88
+ // TBTC, P2WPKH
86
89
address , err := device .BTCAddress (
87
90
messages .BTCCoin_TBTC ,
88
91
[]uint32 {
@@ -97,6 +100,43 @@ func TestBTCAddress(t *testing.T) {
97
100
)
98
101
require .NoError (t , err )
99
102
require .Equal (t , "tb1qq064dxjgl9h9wzgsmzy6t6306qew42w9ka02u3" , address )
103
+
104
+ // BTC, P2WPKH
105
+ address , err = device .BTCAddress (
106
+ messages .BTCCoin_BTC ,
107
+ []uint32 {
108
+ 84 + hardenedKeyStart ,
109
+ 0 + hardenedKeyStart ,
110
+ 0 + hardenedKeyStart ,
111
+ 1 ,
112
+ 10 ,
113
+ },
114
+ NewBTCScriptConfigSimple (messages .BTCScriptConfig_P2WPKH ),
115
+ false ,
116
+ )
117
+ require .NoError (t , err )
118
+ require .Equal (t , "bc1qcq0ceq9vs24g4tnkkx3k2rry9j44r74huc3d7s" , address )
119
+
120
+ // RBTC, P2WPKH
121
+ address , err = device .BTCAddress (
122
+ messages .BTCCoin_RBTC ,
123
+ []uint32 {
124
+ 84 + hardenedKeyStart ,
125
+ 1 + hardenedKeyStart ,
126
+ 0 + hardenedKeyStart ,
127
+ 1 ,
128
+ 10 ,
129
+ },
130
+ NewBTCScriptConfigSimple (messages .BTCScriptConfig_P2WPKH ),
131
+ false ,
132
+ )
133
+ // Regtest (RBTC) support added in v9.21.0
134
+ if device .Version ().AtLeast (semver .NewSemVer (9 , 21 , 0 )) {
135
+ require .NoError (t , err )
136
+ require .Equal (t , "bcrt1qq064dxjgl9h9wzgsmzy6t6306qew42w955k8tc" , address )
137
+ } else {
138
+ require .Error (t , err )
139
+ }
100
140
})
101
141
}
102
142
@@ -114,7 +154,7 @@ func simulatorPub(t *testing.T, device *Device, keypath ...uint32) *btcec.Public
114
154
}
115
155
116
156
func TestSimulatorBTCSignMessage (t * testing.T ) {
117
- testInitializedSimulators (t , func (t * testing.T , device * Device ) {
157
+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes. Buffer ) {
118
158
t .Helper ()
119
159
coin := messages .BTCCoin_BTC
120
160
keypath := []uint32 {49 + hardenedKeyStart , 0 + hardenedKeyStart , 0 + hardenedKeyStart , 0 , 10 }
@@ -206,7 +246,7 @@ func TestSimulatorBTCXPub(t *testing.T) {
206
246
})
207
247
}
208
248
209
- func TestSimulatorBTCAddress (t * testing.T ) {
249
+ func TestBTCAddress (t * testing.T ) {
210
250
testConfigurations (t , func (t * testing.T , env * testEnv ) {
211
251
t .Helper ()
212
252
expected := "mocked-address"
@@ -341,7 +381,7 @@ func makeTaprootOutput(t *testing.T, pubkey *btcec.PublicKey) (*btcec.PublicKey,
341
381
342
382
// Test signing; all inputs are BIP86 Taproot keyspends.
343
383
func TestSimulatorBTCSignTaprootKeySpend (t * testing.T ) {
344
- testInitializedSimulators (t , func (t * testing.T , device * Device ) {
384
+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes. Buffer ) {
345
385
t .Helper ()
346
386
coin := messages .BTCCoin_BTC
347
387
accountKeypath := []uint32 {86 + hardenedKeyStart , 0 + hardenedKeyStart , 0 + hardenedKeyStart }
@@ -385,6 +425,7 @@ func TestSimulatorBTCSignTaprootKeySpend(t *testing.T) {
385
425
_ , _ , err := device .BTCSign (
386
426
coin ,
387
427
scriptConfigs ,
428
+ nil ,
388
429
& BTCTx {
389
430
Version : 2 ,
390
431
Inputs : []* BTCTxInput {
@@ -431,7 +472,7 @@ func TestSimulatorBTCSignTaprootKeySpend(t *testing.T) {
431
472
432
473
// Test signing; mixed input types (p2wpkh, p2wpkh-p2sh, p2tr)
433
474
func TestSimulatorBTCSignMixed (t * testing.T ) {
434
- testInitializedSimulators (t , func (t * testing.T , device * Device ) {
475
+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes. Buffer ) {
435
476
t .Helper ()
436
477
coin := messages .BTCCoin_BTC
437
478
changeKeypath := []uint32 {86 + hardenedKeyStart , 0 + hardenedKeyStart , 0 + hardenedKeyStart , 1 , 0 }
@@ -513,6 +554,7 @@ func TestSimulatorBTCSignMixed(t *testing.T) {
513
554
_ , _ , err := device .BTCSign (
514
555
coin ,
515
556
scriptConfigs ,
557
+ nil ,
516
558
& BTCTx {
517
559
Version : 2 ,
518
560
Inputs : []* BTCTxInput {
@@ -573,7 +615,7 @@ func TestSimulatorBTCSignMixed(t *testing.T) {
573
615
// Test that we can send to a silent payment output (generated by the BitBox) and verify the
574
616
// corresponding DLEQ proof on the host that the output was generated correctly.
575
617
func TestSimulatorBTCSignSilentPayment (t * testing.T ) {
576
- testInitializedSimulators (t , func (t * testing.T , device * Device ) {
618
+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes. Buffer ) {
577
619
t .Helper ()
578
620
coin := messages .BTCCoin_BTC
579
621
accountKeypath := []uint32 {86 + hardenedKeyStart , 0 + hardenedKeyStart , 0 + hardenedKeyStart }
@@ -614,6 +656,7 @@ func TestSimulatorBTCSignSilentPayment(t *testing.T) {
614
656
Keypath : accountKeypath ,
615
657
},
616
658
},
659
+ nil ,
617
660
& BTCTx {
618
661
Version : 2 ,
619
662
Inputs : []* BTCTxInput {
@@ -671,3 +714,180 @@ func TestSimulatorBTCSignSilentPayment(t *testing.T) {
671
714
}
672
715
})
673
716
}
717
+
718
+ // Tests that the BitBox displays the output as being of the same account in a self-send.
719
+ func TestSimulatorSignBTCTransactionSendSelfSameAccount (t * testing.T ) {
720
+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes.Buffer ) {
721
+ t .Helper ()
722
+ coin := messages .BTCCoin_BTC
723
+
724
+ input0Keypath := []uint32 {86 + hardenedKeyStart , 0 + hardenedKeyStart , 0 + hardenedKeyStart , 0 , 0 }
725
+ input1Keypath := []uint32 {86 + hardenedKeyStart , 0 + hardenedKeyStart , 0 + hardenedKeyStart , 0 , 1 }
726
+
727
+ prevTx := & wire.MsgTx {
728
+ Version : 2 ,
729
+ TxIn : []* wire.TxIn {
730
+ {
731
+ PreviousOutPoint : * mustOutpoint ("3131313131313131313131313131313131313131313131313131313131313131:0" ),
732
+ Sequence : 0xFFFFFFFF ,
733
+ },
734
+ },
735
+ TxOut : []* wire.TxOut {
736
+ {
737
+ Value : 100_000_000 ,
738
+ PkScript : func () []byte {
739
+ _ , script := makeTaprootOutput (t , simulatorPub (t , device , input0Keypath ... ))
740
+ return script
741
+ }(),
742
+ },
743
+ },
744
+ LockTime : 0 ,
745
+ }
746
+ convertedPrevTx := NewBTCPrevTxFromBtcd (prevTx )
747
+
748
+ scriptConfigs := []* messages.BTCScriptConfigWithKeypath {
749
+ {
750
+ ScriptConfig : NewBTCScriptConfigSimple (messages .BTCScriptConfig_P2TR ),
751
+ Keypath : input0Keypath [:3 ],
752
+ },
753
+ }
754
+
755
+ prevTxHash := prevTx .TxHash ()
756
+ _ , _ , err := device .BTCSign (
757
+ coin ,
758
+ scriptConfigs ,
759
+ nil ,
760
+ & BTCTx {
761
+ Version : 2 ,
762
+ Inputs : []* BTCTxInput {
763
+ {
764
+ Input : & messages.BTCSignInputRequest {
765
+ PrevOutHash : prevTxHash [:],
766
+ PrevOutIndex : 0 ,
767
+ PrevOutValue : uint64 (prevTx .TxOut [0 ].Value ),
768
+ Sequence : 0xFFFFFFFF ,
769
+ Keypath : input0Keypath ,
770
+ ScriptConfigIndex : 0 ,
771
+ },
772
+ PrevTx : convertedPrevTx ,
773
+ },
774
+ },
775
+ Outputs : []* messages.BTCSignOutputRequest {
776
+ {
777
+ Ours : true ,
778
+ Value : 70_000_000 ,
779
+ Keypath : input1Keypath ,
780
+ },
781
+ },
782
+ Locktime : 0 ,
783
+ },
784
+ messages .BTCSignInitRequest_DEFAULT ,
785
+ )
786
+ require .NoError (t , err )
787
+
788
+ switch {
789
+ // Display changed in v9.22.0.
790
+ case device .Version ().AtLeast (semver .NewSemVer (9 , 22 , 0 )):
791
+ require .Contains (t ,
792
+ stdOut .String (),
793
+ "This BitBox (same account): bc1psz0tsdr9sgnukfcx4gtwpp5exyeqdycfqjvm2jw6tvsj3k3eavts20yuag" ,
794
+ )
795
+ case device .Version ().AtLeast (semver .NewSemVer (9 , 20 , 0 )):
796
+ require .Contains (t ,
797
+ stdOut .String (),
798
+ "This BitBox02: bc1psz0tsdr9sgnukfcx4gtwpp5exyeqdycfqjvm2jw6tvsj3k3eavts20yuag" ,
799
+ )
800
+ }
801
+ // Before simulator v9.20, address confirmation data was not written to stdout.
802
+ })
803
+ }
804
+
805
+ // Tests that the BitBox displays the output as being of the same keystore, but different account.
806
+ func TestSimulatorSignBTCTransactionSendSelfDifferentAccount (t * testing.T ) {
807
+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes.Buffer ) {
808
+ t .Helper ()
809
+ coin := messages .BTCCoin_BTC
810
+
811
+ input0Keypath := []uint32 {86 + hardenedKeyStart , 0 + hardenedKeyStart , 0 + hardenedKeyStart , 0 , 0 }
812
+ input1Keypath := []uint32 {86 + hardenedKeyStart , 0 + hardenedKeyStart , 1 + hardenedKeyStart , 0 , 0 }
813
+
814
+ prevTx := & wire.MsgTx {
815
+ Version : 2 ,
816
+ TxIn : []* wire.TxIn {
817
+ {
818
+ PreviousOutPoint : * mustOutpoint ("3131313131313131313131313131313131313131313131313131313131313131:0" ),
819
+ Sequence : 0xFFFFFFFF ,
820
+ },
821
+ },
822
+ TxOut : []* wire.TxOut {
823
+ {
824
+ Value : 100_000_000 ,
825
+ PkScript : func () []byte {
826
+ _ , script := makeTaprootOutput (t , simulatorPub (t , device , input0Keypath ... ))
827
+ return script
828
+ }(),
829
+ },
830
+ },
831
+ LockTime : 0 ,
832
+ }
833
+ convertedPrevTx := NewBTCPrevTxFromBtcd (prevTx )
834
+
835
+ scriptConfigs := []* messages.BTCScriptConfigWithKeypath {
836
+ {
837
+ ScriptConfig : NewBTCScriptConfigSimple (messages .BTCScriptConfig_P2TR ),
838
+ Keypath : input0Keypath [:3 ],
839
+ },
840
+ }
841
+ outputScriptConfigs := []* messages.BTCScriptConfigWithKeypath {
842
+ {
843
+ ScriptConfig : NewBTCScriptConfigSimple (messages .BTCScriptConfig_P2TR ),
844
+ Keypath : input1Keypath [:3 ],
845
+ },
846
+ }
847
+ outputScriptConfigIndex := uint32 (0 )
848
+
849
+ prevTxHash := prevTx .TxHash ()
850
+ _ , _ , err := device .BTCSign (
851
+ coin ,
852
+ scriptConfigs ,
853
+ outputScriptConfigs ,
854
+ & BTCTx {
855
+ Version : 2 ,
856
+ Inputs : []* BTCTxInput {
857
+ {
858
+ Input : & messages.BTCSignInputRequest {
859
+ PrevOutHash : prevTxHash [:],
860
+ PrevOutIndex : 0 ,
861
+ PrevOutValue : uint64 (prevTx .TxOut [0 ].Value ),
862
+ Sequence : 0xFFFFFFFF ,
863
+ Keypath : input0Keypath ,
864
+ ScriptConfigIndex : 0 ,
865
+ },
866
+ PrevTx : convertedPrevTx ,
867
+ },
868
+ },
869
+ Outputs : []* messages.BTCSignOutputRequest {
870
+ {
871
+ Ours : true ,
872
+ Value : 70_000_000 ,
873
+ Keypath : input1Keypath ,
874
+ OutputScriptConfigIndex : & outputScriptConfigIndex ,
875
+ },
876
+ },
877
+ Locktime : 0 ,
878
+ },
879
+ messages .BTCSignInitRequest_DEFAULT ,
880
+ )
881
+
882
+ // Introduced in v9.22.0.
883
+ if ! device .Version ().AtLeast (semver .NewSemVer (9 , 22 , 0 )) {
884
+ require .EqualError (t , err , UnsupportedError ("9.22.0" ).Error ())
885
+ return
886
+ }
887
+ require .NoError (t , err )
888
+ require .Contains (t ,
889
+ stdOut .String (),
890
+ "This BitBox (account #2): bc1pzeyhtmk2d5jrjunam30dus0p34095m622dq7trm7r0g8pwac2gvqxh8d47" ,
891
+ )
892
+ })
893
+ }
0 commit comments