@@ -212,6 +212,197 @@ mod tests {
212
212
use bitbox02:: testing:: { mock, mock_unlocked, Data , MUTEX } ;
213
213
use util:: bip32:: HARDENED ;
214
214
215
+ #[ test]
216
+ pub fn test_xpub ( ) {
217
+ let _guard = MUTEX . lock ( ) . unwrap ( ) ;
218
+ struct Test < ' a > {
219
+ coin : BtcCoin ,
220
+ keypath : & ' a [ u32 ] ,
221
+ xpub_type : XPubType ,
222
+ expected_xpub : & ' a str ,
223
+ expected_display_title : & ' a str ,
224
+ }
225
+
226
+ for test in vec ! [
227
+ // BTC P2WPKH-P2SH
228
+ Test {
229
+ coin: BtcCoin :: Btc ,
230
+ keypath: & [ 49 + HARDENED , 0 + HARDENED , 0 + HARDENED ] ,
231
+ xpub_type: XPubType :: Xpub ,
232
+ expected_xpub: "xpub6Bj8T8R98MTKGDcMpJnoKeHR54EF1JJohA2HLs2WeNiaZ9UdNVvAbYpPnVd3Mcymabx7fYDKx4ubku1DTPRoDzpziD4qK3vxN9FEiF25Hgx" ,
233
+ expected_display_title: "Bitcoin\n account #1" ,
234
+ } ,
235
+ Test {
236
+ coin: BtcCoin :: Btc ,
237
+ keypath: & [ 49 + HARDENED , 0 + HARDENED , 0 + HARDENED ] ,
238
+ xpub_type: XPubType :: Ypub ,
239
+ expected_xpub: "ypub6WZPko64H2zo7WoUefaRXjNvF2NgwvJJcGYW8FvQ2P6TcFHrdA5jDcUXohadMXdgzF4vR1otQjG9eBcnB5qp2EWbaYmFtxkSdsJt6svswWd" ,
240
+ expected_display_title: "Bitcoin\n account #1" ,
241
+ } ,
242
+ Test {
243
+ coin: BtcCoin :: Btc ,
244
+ keypath: & [ 49 + HARDENED , 0 + HARDENED , 0 + HARDENED ] ,
245
+ xpub_type: XPubType :: Zpub ,
246
+ expected_xpub: "zpub6qPf4TkyRiYGxozbV2N3jpURQzX8tYHoXP4iuepHQPULfM75spFHqg8fpuYDMSHcPtBjAVQSsPchXUELtnFppUCCStTgUsZvubNXVPGWjcc" ,
247
+ expected_display_title: "Bitcoin\n account #1" ,
248
+ } ,
249
+ Test {
250
+ coin: BtcCoin :: Btc ,
251
+ keypath: & [ 84 + HARDENED , 0 + HARDENED , 1 + HARDENED ] ,
252
+ xpub_type: XPubType :: Xpub ,
253
+ expected_xpub: "xpub6Bh4PT7iTyf6EHrFhc2ZaRYQxiLexYJQ7DtnNSNipD19JRV5jUW4gVHV9ouWvRY6DbbfyQhjP9E7LQ9QuR1SkPMnMi8NP3o2WtnWZim6Dqd" ,
254
+ expected_display_title: "Bitcoin\n account #2" ,
255
+ } ,
256
+ // BTC P2WPKH
257
+ Test {
258
+ coin: BtcCoin :: Btc ,
259
+ keypath: & [ 84 + HARDENED , 0 + HARDENED , 1 + HARDENED ] ,
260
+ xpub_type: XPubType :: Zpub ,
261
+ expected_xpub: "zpub6qMaznTYmLk3vtEVNKbozbjRJedYqnHPwSwDwEAVaDkuQd7YEnqBvcbmCDpgvEqw2sqHUMtrJTwD6yNYLoqULriz6PXDYsS14LuoLr3KxUC" ,
262
+ expected_display_title: "Bitcoin\n account #2" ,
263
+ } ,
264
+ // TBTC P2WPKH-P2SH
265
+ Test {
266
+ coin: BtcCoin :: Tbtc ,
267
+ keypath: & [ 49 + HARDENED , 1 + HARDENED , 0 + HARDENED ] ,
268
+ xpub_type: XPubType :: Xpub ,
269
+ expected_xpub: "xpub6BmN7k2vQY7D5jQpmKErAMNRqgtDMz9ePjR83SRAR6GAiWr63z7QLBPvsEQ2ghgT8hm1BoeApuS3paSmGmax2u3ggETCfWJvCEu6jCZDneX" ,
270
+ expected_display_title: "BTC Testnet\n account #1" ,
271
+ } ,
272
+ Test {
273
+ coin: BtcCoin :: Tbtc ,
274
+ keypath: & [ 49 + HARDENED , 1 + HARDENED , 0 + HARDENED ] ,
275
+ xpub_type: XPubType :: Tpub ,
276
+ expected_xpub: "tpubDC8zdyrc7p4fMXbgDWDwNGhoAoysMNehwN1RPzUJm124ToWo8CxVUd4m7GUpDCdgvcHuoPA3N1G6WkwNfdSBvLVyjqCWM2y9nCVWVGLFiLh" ,
277
+ expected_display_title: "BTC Testnet\n account #1" ,
278
+ } ,
279
+ // TBTC P2WPKH
280
+ Test {
281
+ coin: BtcCoin :: Tbtc ,
282
+ keypath: & [ 84 + HARDENED , 1 + HARDENED , 0 + HARDENED ] ,
283
+ xpub_type: XPubType :: Xpub ,
284
+ expected_xpub: "xpub6Bs9jH3KF6w5ibrAdLAvY4759RnU74dnmUZ42m5FMqoFQoW9xL6co535xiGzaZMXrYn3nqk94ruLVfArx7sxvUvoXeF3FvXLX9T2dgTLGgc" ,
285
+ expected_display_title: "BTC Testnet\n account #1" ,
286
+ } ,
287
+ Test {
288
+ coin: BtcCoin :: Tbtc ,
289
+ keypath: & [ 84 + HARDENED , 1 + HARDENED , 0 + HARDENED ] ,
290
+ xpub_type: XPubType :: Tpub ,
291
+ expected_xpub: "tpubDCEnFWrzxNtXzQ325XA1jySSUYt86T8rK79MPK8PhkZ9A6As2YwhwWhvCkMn74JmeTJxQRG1bxjPBqfULyjCovP6bEzLwTBa773SPehtXCt" ,
292
+ expected_display_title: "BTC Testnet\n account #1" ,
293
+ } ,
294
+ // LTC P2WPKH-P2SH
295
+ Test {
296
+ coin: BtcCoin :: Ltc ,
297
+ keypath: & [ 49 + HARDENED , 2 + HARDENED , 0 + HARDENED ] ,
298
+ xpub_type: XPubType :: Xpub ,
299
+ expected_xpub: "xpub6CC3f5yryzDqxUWHSFz69BcjP1yB7dX3d4MNoyCrc77Z3iAmDdfSmsTR2wCH4WnAhPcmRyAn4tnQsxBD9E1A3DiZ4PA81FUGCYXkJ5hUmEu" ,
300
+ expected_display_title: "Litecoin\n account #1" ,
301
+ } ,
302
+ // LTC P2WPKH
303
+ Test {
304
+ coin: BtcCoin :: Ltc ,
305
+ keypath: & [ 84 + HARDENED , 2 + HARDENED , 0 + HARDENED ] ,
306
+ xpub_type: XPubType :: Xpub ,
307
+ expected_xpub: "xpub6CJNSECzxso6VQF15vTqSMUCLDfYytpKgbCEtuMTs6Sbjd3CGUoXynTvQYWDBThN337scHJnjqnQrL31ttZFa9CicdB3pRodqWxyEQwnrqm" ,
308
+ expected_display_title: "Litecoin\n account #1" ,
309
+ } ,
310
+ ] {
311
+ mock_unlocked ( ) ;
312
+
313
+ // Without display.
314
+ let mut req = pb:: BtcPubRequest {
315
+ coin : test. coin as _ ,
316
+ keypath : test. keypath . to_vec ( ) ,
317
+ display : false ,
318
+ output : Some ( Output :: XpubType ( test. xpub_type as _ ) ) ,
319
+ } ;
320
+
321
+ assert_eq ! (
322
+ block_on( process_pub( & req) ) ,
323
+ Some ( Ok ( Response :: Pub ( pb:: PubResponse {
324
+ r#pub: test. expected_xpub. into( ) ,
325
+ } ) ) ) ,
326
+ ) ;
327
+
328
+ // With display.
329
+ req. display = true ;
330
+ let expected_display_title = test. expected_display_title . clone ( ) ;
331
+ let expected_xpub = test. expected_xpub . clone ( ) ;
332
+ mock ( Data {
333
+ ui_confirm_create : Some ( Box :: new ( move |params| {
334
+ assert_eq ! ( params. title, expected_display_title) ;
335
+ assert_eq ! ( params. body, expected_xpub) ;
336
+ assert ! ( params. scrollable) ;
337
+ true
338
+ } ) ) ,
339
+ ..Default :: default ( )
340
+ } ) ;
341
+ mock_unlocked ( ) ;
342
+ assert_eq ! (
343
+ block_on( process_pub( & req) ) ,
344
+ Some ( Ok ( Response :: Pub ( pb:: PubResponse {
345
+ r#pub: test. expected_xpub. into( ) ,
346
+ } ) ) ) ,
347
+ ) ;
348
+ }
349
+
350
+ // --- Negative tests
351
+ mock_unlocked ( ) ;
352
+ // -- Invalid keypath for BTC
353
+ assert ! ( block_on( process_pub( & pb:: BtcPubRequest {
354
+ coin: BtcCoin :: Btc as _,
355
+ keypath: [ 49 + HARDENED , 0 + HARDENED , 100 + HARDENED ] . to_vec( ) ,
356
+ display: false ,
357
+ output: Some ( Output :: XpubType ( XPubType :: Xpub as _) ) ,
358
+ } ) )
359
+ . unwrap( )
360
+ . is_err( ) ) ;
361
+ // -- Invalid keypath for BTC
362
+ assert ! ( block_on( process_pub( & pb:: BtcPubRequest {
363
+ coin: BtcCoin :: Btc as _,
364
+ keypath: [ 49 + HARDENED , 2 + HARDENED , 0 + HARDENED ] . to_vec( ) ,
365
+ display: false ,
366
+ output: Some ( Output :: XpubType ( XPubType :: Xpub as _) ) ,
367
+ } ) )
368
+ . unwrap( )
369
+ . is_err( ) ) ;
370
+ // -- Invalid keypath for TBTC
371
+ assert ! ( block_on( process_pub( & pb:: BtcPubRequest {
372
+ coin: BtcCoin :: Tbtc as _,
373
+ keypath: [ 49 + HARDENED , 0 + HARDENED , 0 + HARDENED ] . to_vec( ) ,
374
+ display: false ,
375
+ output: Some ( Output :: XpubType ( XPubType :: Xpub as _) ) ,
376
+ } ) )
377
+ . unwrap( )
378
+ . is_err( ) ) ;
379
+ // -- Invalid keypath for LTC
380
+ assert ! ( block_on( process_pub( & pb:: BtcPubRequest {
381
+ coin: BtcCoin :: Ltc as _,
382
+ keypath: [ 49 + HARDENED , 0 + HARDENED , 0 + HARDENED ] . to_vec( ) ,
383
+ display: false ,
384
+ output: Some ( Output :: XpubType ( XPubType :: Xpub as _) ) ,
385
+ } ) )
386
+ . unwrap( )
387
+ . is_err( ) ) ;
388
+
389
+ let req = pb:: BtcPubRequest {
390
+ coin : BtcCoin :: Btc as _ ,
391
+ keypath : [ 49 + HARDENED , 0 + HARDENED , 0 + HARDENED ] . to_vec ( ) ,
392
+ display : false ,
393
+ output : Some ( Output :: XpubType ( XPubType :: Xpub as _ ) ) ,
394
+ } ;
395
+
396
+ // -- Wrong coin: MIN-1
397
+ let mut req_invalid = req. clone ( ) ;
398
+ req_invalid. coin = BtcCoin :: Btc as i32 - 1 ;
399
+ assert ! ( block_on( process_pub( & req_invalid) ) . unwrap( ) . is_err( ) ) ;
400
+ // -- Wrong coin: MAX + 1
401
+ let mut req_invalid = req. clone ( ) ;
402
+ req_invalid. coin = BtcCoin :: Tltc as i32 + 1 ;
403
+ assert ! ( block_on( process_pub( & req_invalid) ) . unwrap( ) . is_err( ) ) ;
404
+ }
405
+
215
406
#[ test]
216
407
pub fn test_address_simple ( ) {
217
408
let _guard = MUTEX . lock ( ) . unwrap ( ) ;
0 commit comments