Skip to content

Commit b6cefdf

Browse files
committed
Merge branch 'xpubs'
2 parents cf47c3f + b472172 commit b6cefdf

19 files changed

Lines changed: 2443 additions & 4286 deletions

api/firmware/btc.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,57 @@ func (device *Device) BTCXPub(
162162
return pubResponse.Pub.Pub, nil
163163
}
164164

165+
// BTCXPubs queries the device for multiple xpubs at a time. On firmware <v9.24.0, this falls back
166+
// to calling `BTCXPub()` for each keypath.
167+
func (device *Device) BTCXPubs(
168+
coin messages.BTCCoin,
169+
keypaths [][]uint32,
170+
xpubType messages.BTCXpubsRequest_XPubType) ([]string, error) {
171+
keypathMsgs := make([]*messages.Keypath, len(keypaths))
172+
if !device.version.AtLeast(semver.NewSemVer(9, 24, 0)) {
173+
// Fallback to fetching them one-by-one on older firmware.
174+
xpubTypeConverted, ok := map[messages.BTCXpubsRequest_XPubType]messages.BTCPubRequest_XPubType{
175+
messages.BTCXpubsRequest_XPUB: messages.BTCPubRequest_XPUB,
176+
messages.BTCXpubsRequest_TPUB: messages.BTCPubRequest_TPUB,
177+
}[xpubType]
178+
if !ok {
179+
return nil, errp.New("unrecongized xpubType")
180+
}
181+
xpubs := make([]string, len(keypaths))
182+
for i, keypath := range keypaths {
183+
xpub, err := device.BTCXPub(coin, keypath, xpubTypeConverted, false)
184+
if err != nil {
185+
return nil, err
186+
}
187+
xpubs[i] = xpub
188+
}
189+
return xpubs, nil
190+
}
191+
192+
for i, keypath := range keypaths {
193+
keypathMsgs[i] = &messages.Keypath{Keypath: keypath}
194+
}
195+
request := &messages.BTCRequest{
196+
Request: &messages.BTCRequest_Xpubs{
197+
Xpubs: &messages.BTCXpubsRequest{
198+
Coin: coin,
199+
XpubType: xpubType,
200+
Keypaths: keypathMsgs,
201+
},
202+
},
203+
}
204+
response, err := device.queryBTC(request)
205+
if err != nil {
206+
return nil, err
207+
}
208+
209+
pubsResponse, ok := response.Response.(*messages.BTCResponse_Pubs)
210+
if !ok {
211+
return nil, errp.New("unexpected response")
212+
}
213+
return pubsResponse.Pubs.Pubs, nil
214+
}
215+
165216
// BTCAddress queries the device for a btc, ltc, tbtc, tltc address.
166217
func (device *Device) BTCAddress(
167218
coin messages.BTCCoin,

api/firmware/btc_test.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func TestNewXPub(t *testing.T) {
106106
}, xpub)
107107
}
108108

109-
func TestBTCXpub(t *testing.T) {
109+
func TestSimulatorBTCXpub(t *testing.T) {
110110
testInitializedSimulators(t, func(t *testing.T, device *Device, stdOut *bytes.Buffer) {
111111
t.Helper()
112112
xpub, err := device.BTCXPub(messages.BTCCoin_TBTC, []uint32{
@@ -119,6 +119,39 @@ func TestBTCXpub(t *testing.T) {
119119
})
120120
}
121121

122+
func TestSimulatorBTCXPubs(t *testing.T) {
123+
testInitializedSimulators(t, func(t *testing.T, device *Device, stdOut *bytes.Buffer) {
124+
t.Helper()
125+
xpubs, err := device.BTCXPubs(messages.BTCCoin_TBTC,
126+
[][]uint32{
127+
{
128+
49 + hardenedKeyStart,
129+
1 + hardenedKeyStart,
130+
0 + hardenedKeyStart,
131+
},
132+
{
133+
84 + hardenedKeyStart,
134+
1 + hardenedKeyStart,
135+
0 + hardenedKeyStart,
136+
},
137+
{
138+
86 + hardenedKeyStart,
139+
1 + hardenedKeyStart,
140+
0 + hardenedKeyStart,
141+
},
142+
}, messages.BTCXpubsRequest_TPUB)
143+
144+
require.NoError(t, err)
145+
require.Equal(t,
146+
[]string{
147+
"tpubDCNtvuCS9oj3psPNfXZXuGjcQ5rSBi3MzigjBqqwQohWWetoRdLzT5v2uJq6KBTwxj1FYvuPTr7RoWkN4cmubDy5wW8SU3q9xYnDRpQepiT",
148+
"tpubDCYNsKenq7Cuuf4fHsu2fsWA7Wb5cTD2qRUrw6uHbNNYQoNkEoJk4hgNhxbnGss5gnEe2MpqN2qbRVqWJGmuofAWmwFFi4CZ9Tg1LHKJDhF",
149+
"tpubDDc6eecoyYxL4g3WKYpbbinyUmnfVikQCzHTPd6rJQivaPqGKBFiueQqWoAYonB8hAEXGM1ak7LqrnwczH24EbW7jbG5bNK5rncmRXtv7nG",
150+
},
151+
xpubs)
152+
})
153+
}
154+
122155
func TestSimulatorBTCAddress(t *testing.T) {
123156
testInitializedSimulators(t, func(t *testing.T, device *Device, stdOut *bytes.Buffer) {
124157
t.Helper()
@@ -212,7 +245,7 @@ func TestSimulatorBTCSignMessage(t *testing.T) {
212245
})
213246
}
214247

215-
func TestSimulatorBTCXPub(t *testing.T) {
248+
func TestBTCXPub(t *testing.T) {
216249
testConfigurations(t, func(t *testing.T, env *testEnv) {
217250
t.Helper()
218251
expected := "mocked-xpub"

api/firmware/device_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,12 @@ func TestSimulatorProduct(t *testing.T) {
536536
testSimulators(t, func(t *testing.T, device *Device, stdOut *bytes.Buffer) {
537537
t.Helper()
538538
require.NoError(t, device.Init())
539-
require.Equal(t, common.ProductBitBox02Multi, device.Product())
539+
// Since v9.24.0, the simulator simulates a Nova device.
540+
if device.Version().AtLeast(semver.NewSemVer(9, 24, 0)) {
541+
require.Equal(t, common.ProductBitBox02PlusMulti, device.Product())
542+
} else {
543+
require.Equal(t, common.ProductBitBox02Multi, device.Product())
544+
}
540545
})
541546
}
542547

api/firmware/messages/antiklepto.pb.go

Lines changed: 40 additions & 90 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)