def test_fee_too_high(self): self.setup_mnemonic_nopin_nopassphrase() # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # input 0: 0.0039 BTC inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=390000, prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, ) out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=390000 - 250000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_FeeOverThreshold), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ], None, True) self.assertEqual(binascii.hexlify(serialized_tx), '010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100a3b17b37de3bfecca47f0d49f7bb0d0f68d45df7defe45713d57e83731f5e3d902205404b14630cea6a88b23a5f7c3a1b88494757a8ca5e1c0b0b93cf3c38231c3bd0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff01e0220200000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000')
def test_apply_settings_passphrase(self): self.setup_mnemonic_pin_nopassphrase() self.assertEqual(self.client.features.passphrase_protection, False) with self.client: self.client.set_expected_responses( [proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(use_passphrase=True) self.assertEqual(self.client.features.passphrase_protection, True) with self.client: self.client.set_expected_responses( [proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(use_passphrase=False) self.assertEqual(self.client.features.passphrase_protection, False) with self.client: self.client.set_expected_responses( [proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(use_passphrase=True) self.assertEqual(self.client.features.passphrase_protection, True)
def test_ping(self): self.setup_mnemonic_pin_passphrase() self.client.clear_session() with self.client: self.client.set_expected_responses([proto.Success()]) res = self.client.ping('random data') self.assertEqual(res, 'random data') with self.client: self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_Ping), proto.Success()]) res = self.client.ping('random data', button_protection=True) self.assertEqual(res, 'random data') with self.client: self.client.set_expected_responses([proto.PinMatrixRequest(), proto.Success()]) res = self.client.ping('random data', pin_protection=True) self.assertEqual(res, 'random data') with self.client: self.client.set_expected_responses([ proto.PassphraseRequest(), proto.ButtonRequest(code=proto_types.ButtonRequest_Other), proto.Success() ]) res = self.client.ping('random data', passphrase_protection=True) self.assertEqual(res, 'random data')
def test_p2sh(self): self.setup_mnemonic_nopin_nopassphrase() inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=400000, prev_hash=binascii.unhexlify('54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3'), prev_index=1, ) out1 = proto_types.TxOutputType(address='3DKGE1pvPpBAgZj94MbCinwmksewUNNYVR', # p2sh amount=400000 - 10000, script_type=proto_types.PAYTOSCRIPTHASH, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("54aa5680dea781f45ebb536e53dffc526d68c0eb5c00547e323b2c32382dfba3"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ]) # Accepted by network: tx 8cc1f4adf7224ce855cf535a5104594a0004cb3b640d6714fdb00b9128832dd5 self.assertEqual(binascii.hexlify(serialized_tx), '0100000001a3fb2d38322c3b327e54005cebc0686d52fcdf536e53bb5ef481a7de8056aa54010000006b4830450221009e020b0390ccad533b73b552f8a99a9d827212c558e4f755503674d07c92ad4502202d606f7316990e0461c51d4add25054f19c697aa3e3c2ced4d568f0b2c57e62f0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0170f305000000000017a9147f844bdb0b8fd54b64e3d16c85dc1170f1ff97c18700000000')
def test_one_one_fee(self): self.setup_mnemonic_nopin_nopassphrase() # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # input 0: 0.0039 BTC inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=390000, prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, ) out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=390000 - 10000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, ], None, True) # Accepted by network: tx fd79435246dee76b2f159d2db08032d666c95adc544de64c8c49f474df4a7fee self.assertEqual(binascii.hexlify(serialized_tx), '010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b4830450221009a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8b7077102202b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5ede7810121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0160cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000')
def test_spend_coinbase(self): # 25 TEST generated to m/1 (mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV) # tx: d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236 # input 0: 25.0027823 BTC self.setup_mnemonic_nopin_nopassphrase() inp1 = proto_types.TxInputType(address_n=[1], # mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV # amount=390000, prev_hash=binascii.unhexlify('d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236'), prev_index=0, ) out1 = proto_types.TxOutputType(address='mm6FM31rM5Vc3sw5D7kztiBg3jHUzyqF1g', amount=2500278230 - 10000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_tx_api(tx_api.TxApiTestnet) self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1, ], [out1, ], None, True) # Accepted by network: tx self.assertEqual(binascii.hexlify(serialized_tx), '010000000136825bfdb78c8ede226c7c4f25a018e99a2c061d63c7fb425fca7c7d6721dad6000000006a473044022047845c366eb24f40be315c7815a154513c444c7989eb80f7ce7ff6aeb703d26a022007c1f5efadf67c5889634fd7ac39a7ce78bffac291673e8772ecd8389c901d9f01210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6ffffffff01c6100795000000001976a9143d2496e67f5f57a924353da42d4725b318e7a8ea88ac00000000')
def test_send_p2sh_change(self): self.setup_mnemonic_allallall() self.client.set_tx_api(TxApiTestnet) inp1 = proto_types.TxInputType( address_n=parse_path("49'/1'/0'/1/0"), # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX amount=123456789, prev_hash=unhexlify( '20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337' ), prev_index=0, script_type=proto_types.SPENDP2SHWITNESS, ) out1 = proto_types.TxOutputType( address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC', amount=12300000, script_type=proto_types.PAYTOADDRESS, ) out2 = proto_types.TxOutputType( address_n=parse_path("49'/1'/0'/1/0"), script_type=proto_types.PAYTOP2SHWITNESS, amount=123456789 - 11000 - 12300000, ) with self.client: self.client.set_expected_responses([ proto.TxRequest( request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest( request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest( code=proto_types.ButtonRequest_ConfirmOutput), proto.TxRequest( request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest( request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest( request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest( request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest( request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2]) self.assertEquals( hexlify(serialized_tx), b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000' )
def test_one_three_fee(self): self.setup_mnemonic_nopin_nopassphrase() # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # input 0: 0.0039 BTC inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=390000, prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, ) # Spend Output address out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=390000 - 80000 - 12000 - 10000, script_type=proto_types.PAYTOADDRESS, address_type=0, ) # Transfer Output address out2 = proto_types.TxOutputType(address_n=[0x8000002c, 0x80000000, 0x80000000, 0, 0 ], amount=10000, script_type=proto_types.PAYTOADDRESS, address_type=1, ) # Change Output address out3 = proto_types.TxOutputType(address_n=[0x8000002c, 0x80000000, 0x80000000, 1, 1 ], amount=80000, script_type=proto_types.PAYTOADDRESS, address_type=2, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmTransferToAccount), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=2)), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=2)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=2)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, out2, out3]) self.assertEqual(binascii.hexlify(serialized_tx), '010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100c3ceed2bd2365ccdb978d605e9ae6347790b978e2747bbbec623364270be723c022017680d050c2bf0dae4bd249d83b43bc93a33661c1a0b18c7e8a05eb47815f9aa0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0300650400000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac10270000000000001976a9149c9d21f47382762df3ad81391ee0964b28dd951788ac80380100000000001976a914db302d9f1dd36faa220d8dfd7ff18ff5e308a53688ac00000000')
def test_two_two(self): self.setup_mnemonic_nopin_nopassphrase() # tx: c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c # input 1: 0.0010 BTC # tx: 58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e # input 1: 0.0011 BTC inp1 = proto_types.TxInputType(address_n=[1], # 1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb # amount=100000, prev_hash=binascii.unhexlify('c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c'), prev_index=1, ) inp2 = proto_types.TxInputType(address_n=[2], # 15AeAhtNJNKyowK8qPHwgpXkhsokzLtUpG # amount=110000, prev_hash=binascii.unhexlify('58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e'), prev_index=1, ) out1 = proto_types.TxOutputType(address='15Jvu3nZNP7u2ipw2533Q9VVgEu2Lu9F2B', amount=210000 - 100000 - 10000, script_type=proto_types.PAYTOADDRESS, ) out2 = proto_types.TxOutputType(address_n=[3], # 1CmzyJp9w3NafXMSEFH4SLYUPAVCSUrrJ5 amount=100000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, inp2], [out1, out2], None, True) # Accepted by network: tx c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb self.assertEqual(binascii.hexlify(serialized_tx), '01000000021c032e5715d1da8115a2fe4f57699e15742fe113b0d2d1ca3b594649d322bec6010000006b483045022100f773c403b2f85a5c1d6c9c4ad69c43de66930fff4b1bc818eb257af98305546a0220443bde4be439f276a6ce793664b463580e210ec6c9255d68354449ac0443c76501210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6ffffffff6ea42cd8d9c8e5441c4c5f85bfe50311078730d2881494f11f4d2257777a4958010000006b48304502210090cff1c1911e771605358a8cddd5ae94c7b60cc96e50275908d9bf9d6367c79f02202bfa72e10260a146abd59d0526e1335bacfbb2b4401780e9e3a7441b0480c8da0121038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3ffffffff02a0860100000000001976a9142f4490d5263906e4887ca2996b9e207af3e7824088aca0860100000000001976a914812c13d97f9159e54e326b481b8f88a73df8507a88ac00000000')
def test_signtx(self): self.setup_mnemonic_pin_passphrase() inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, ) out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=390000 - 10000, script_type=proto_types.PAYTOADDRESS, ) tx_responses = [ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXFINISHED), ] self.client.clear_session() with self.client: # Pin & Passphrase are needed after device is locked self.client.set_expected_responses([ proto.PinMatrixRequest(), proto.PassphraseRequest(), ] + tx_responses) self.client.sign_tx('Bitcoin', [inp1, ], [out1, ]) with self.client: # Pin & Passphrase not needed, since they're cached, and the device is unlocked self.client.set_expected_responses([ ] + tx_responses) self.client.sign_tx('Bitcoin', [inp1, ], [out1, ]) self.client.clear_session() with self.client: # Pin & Passphrase needed again after session is cleared, and the device is locked self.client.set_expected_responses([ proto.PinMatrixRequest(), proto.PassphraseRequest(), ] + tx_responses) self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])
def test_reset_device(self): with self.client: self.client.set_expected_responses([proto.EntropyRequest(), \ proto.ButtonRequest(), proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.reset_device(False, 128, True, False, 'label', 'english') # This must fail, because device is already initialized self.assertRaises(Exception, self.client.reset_device, False, 128, True, False, 'label', 'english')
def test_ping(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.clear_session() self.client.set_expected_responses([ proto.ButtonRequest(), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.ButtonRequest(), proto.Success() ]) self.client.ping('msg', True, True, True)
def test_one_three_fee(self): self.setup_mnemonic_nopin_nopassphrase() # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # input 0: 0.0039 BTC inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=390000, prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, ) out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=390000 - 80000 - 12000 - 10000, script_type=proto_types.PAYTOADDRESS, ) out2 = proto_types.TxOutputType(address='13uaUYn6XAooo88QvAqAVsiVvr2mAXutqP', amount=12000, script_type=proto_types.PAYTOADDRESS, ) out3 = proto_types.TxOutputType(address_n=[1], amount=80000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=2)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=2)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=2)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, out2, out3]) self.assertEqual(binascii.hexlify(serialized_tx), '010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100e695e2c530c7c0fc32e6b79b7cff56a7f70a8c9da787534f46b4204070f914fc02207b0879a81408a11e23b11d4c7965c62b5fc6d5c2d92340f5ee2da7b40e99314a0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0300650400000000001976a914de9b2a8da088824e8fe51debea566617d851537888ace02e0000000000001976a9141fe1d337fb81afca42818051e12fd18245d1b17288ac80380100000000001976a9140223b1a09138753c9cb0baf95a0a62c82711567a88ac00000000')
def test_sign_message(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.clear_session() self.client.set_expected_responses([ proto.ButtonRequest(), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.ButtonRequest(), proto.MessageSignature() ]) self.client.sign_message('Bitcoin', [], 'testing message')
def test_send_multisig_1(self): self.setup_mnemonic_allallall() self.client.set_tx_api(TxApiTestnet) nodes = map(lambda index: self.client.get_public_node(parse_path("999'/1'/%d'" % index)), range(1, 4)) multisig = proto_types.MultisigRedeemScriptType( pubkeys=list(map(lambda n: proto_types.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 0]), nodes)), signatures=[b'', b'', b''], m=2, ) inp1 = proto_types.TxInputType( address_n=parse_path("999'/1'/1'/2/0"), prev_hash=unhexlify('9c31922be756c06d02167656465c8dc83bb553bf386a3f478ae65b5c021002be'), prev_index=1, script_type=proto_types.SPENDP2SHWITNESS, multisig=multisig, amount=1610436 ) out1 = proto_types.TxOutputType(address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC', amount=1605000, script_type=proto_types.PAYTOADDRESS) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures1, _) = self.client.sign_tx('Testnet', [inp1], [out1]) # store signature inp1.multisig.signatures[0] = signatures1[0] # sign with third key inp1.address_n[2] = 0x80000003 self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures2, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1]) self.assertEqual(hexlify(serialized_tx), b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402205b44c20cf2681690edaaf7cd2e30d4704124dd8b7eb1fb7f459d3906c3c374a602205ca359b6544ce2c101c979899c782f7d141c3b0454ea69202b1fb4c09d3b715701473044022052fafa64022554ae436dbf781e550bf0d326fef31eea1438350b3ff1940a180102202851bd19203b7fe8582a9ef52e82aa9f61cd52d4bcedfe6dcc0cf782468e6a8e01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000')
def test_ping_format_specifier_sanitize(self): self.setup_mnemonic_pin_passphrase() self.client.clear_session() with self.client: self.client.set_expected_responses([ proto.ButtonRequest(code=proto_types.ButtonRequest_Ping), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.ButtonRequest(code=proto_types.ButtonRequest_Other), proto.Success() ]) res = self.client.ping('%s%x%n%p', button_protection=True, pin_protection=True, passphrase_protection=True) self.assertEqual(res, '%s%x%n%p')
def test_xfer_change_fee(self): self.setup_mnemonic_nopin_nopassphrase() # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # input 0: 0.0039 BTC inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=390000, prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, ) # Transfer Output address out1 = proto_types.TxOutputType(address_n=[0x8000002c, 0x80000000, 0x80000000, 0, 0 ], amount=390000 - 10000, script_type=proto_types.PAYTOADDRESS, address_type=1, ) # Change Output address out2 = proto_types.TxOutputType(address_n=[0x8000002c, 0x80000000, 0x80000000, 1, 1 ], amount=8000, script_type=proto_types.PAYTOADDRESS, address_type=2, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmTransferToAccount), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, out2]) self.assertEqual(binascii.hexlify(serialized_tx), '010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006a473044022029270ff6991d953cb89135dc43723a64f5be00a69db42efeb845f2918dec50c302201f6589bb44c9c4b6c8152966d5de9b56c2a6ca61172d0f63c6c62e48ad8975130121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0260cc0500000000001976a9149c9d21f47382762df3ad81391ee0964b28dd951788ac401f0000000000001976a914db302d9f1dd36faa220d8dfd7ff18ff5e308a53688ac00000000')
def test_not_enough_funds(self): self.setup_mnemonic_nopin_nopassphrase() # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882 # input 0: 0.0039 BTC inp1 = proto_types.TxInputType(address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e # amount=390000, prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'), prev_index=0, ) out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=400000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.Failure(code=proto_types.Failure_NotEnoughFunds) ]) try: self.client.sign_tx('Bitcoin', [inp1, ], [out1, ]) except CallException as e: self.assertEqual(e.args[0], proto_types.Failure_NotEnoughFunds) else: self.assert_(False, "types.Failure_NotEnoughFunds expected")
def test_block_2(self): # https://www.nanode.co/block/2568bf76336f7a415ca236dab97c1df9de951ca057a2e79df1322e647a259e7b self.setup_mnemonic_nopin_nopassphrase() with self.client: self.client.set_expected_responses([ proto.ButtonRequest( code=proto_types.ButtonRequest_ConfirmOutput), proto_nano.NanoSignedTx(), ]) res = self.client.nano_sign_tx( 'Nano', NANO_ACCOUNT_0_PATH, parent_link=unhexlify( '491fca2c69a84607d374aaf1f6acd3ce70744c5be0721b5ed394653e85233507' ), parent_representative=REP_OFFICIAL_1, parent_balance=96242336390000000000000000000, representative=REP_NANODE, balance=96242336390000000000000000000, ) self.assertIsInstance(res, proto_nano.NanoSignedTx) self.assertEqual( hexlify(res.block_hash), '2568bf76336f7a415ca236dab97c1df9de951ca057a2e79df1322e647a259e7b' ) self.assertEqual( hexlify(res.signature), '3a0687542405163d5623808052042b3482360a82cc003d178a0c0d8bfbca86450975d0faec60ae5ac37feba9a8e2205c8540317b26f2c589c2a6578b03870403' )
def test_block_6(self): # https://www.nanode.co/block/a7e59d38b001d9348dbe16fa866d0b435259d381af1db019f3ff83fd7590e226 self.setup_mnemonic_nopin_nopassphrase() with self.client: self.client.set_expected_responses([ proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto_nano.NanoSignedTx(), ]) res = self.client.nano_sign_tx( 'Nano', NANO_ACCOUNT_0_PATH, grandparent_hash=unhexlify( '32ac7d8f5a16a498abf203b8dfee623c9e111ff25e7339f8cd69ec7492b23edd' ), parent_link=unhexlify(NANO_ACCOUNT_1_PUBLICKEY), parent_representative=REP_NANODE, parent_balance=86242336390000000000000000000, link_recipient_n=OTHER_ACCOUNT_3_PATH, representative=REP_NANODE, balance=40000760000000000000000000000, ) self.assertIsInstance(res, proto_nano.NanoSignedTx) self.assertEqual( hexlify(res.block_hash), 'a7e59d38b001d9348dbe16fa866d0b435259d381af1db019f3ff83fd7590e226' ) self.assertEqual( hexlify(res.signature), '1dcd8a27aeac1cab9a2054d5cc6df1b80be46290596dcf6d195c2c286b1615d4139276f9be9c6f202ee1ee8a5569b4a4fc838b1d7306aa71c8e431a6b8075707' )
def test_block_5(self): # https://www.nanode.co/block/5d732d843c22f806011127655790484dbabd38dda20b24900c053c3dfc12523f self.setup_mnemonic_nopin_nopassphrase() with self.client: self.client.set_expected_responses([ proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto_nano.NanoSignedTx(), ]) res = self.client.nano_sign_tx( 'Nano', NANO_ACCOUNT_0_PATH, grandparent_hash=unhexlify( '1ca240212838d053ecaa9dceee598c52a6080067edecaeede3319eb0b7db6525' ), parent_link=unhexlify(RECIPIENT_DONATIONS_PUBLICKEY), parent_representative=REP_NANODE, parent_balance=126242336390000000000000000000, link_recipient_n=NANO_ACCOUNT_1_PATH, representative=REP_NANODE, balance=86242336390000000000000000000, ) self.assertIsInstance(res, proto_nano.NanoSignedTx) self.assertEqual( hexlify(res.block_hash), '5d732d843c22f806011127655790484dbabd38dda20b24900c053c3dfc12523f' ) self.assertEqual( hexlify(res.signature), '3fb596c34db1241201983cbf613fe9b68a6eae2420c7f294c7e883574fda10d5cc19c9e516b57ed0cbc5e7d3438f70f2ddd7a45bf3e693ff800b97e187de5701' )
def test_standard(self): self.requires_firmware("6.3.0") self.setup_mnemonic_nopin_nopassphrase() vec = [ ("cosmos15cenya0tr7nm3tz2wn3h3zwkht2rxrq7q7h3dj", parse_path(DEFAULT_BIP32_PATH)), ("cosmos1kae7mmy87v7qudnz2tk3ctn0c4ut5vccqg63tw", parse_path("m/44h/118h/1h/0/0")), ("cosmos1qpjr794gfnsp4c8uu84xl9xudea7h2tzns7ct8", parse_path("m/44h/118h/12345678h/0/0")), ] for (expected, path) in vec: with self.client: self.client.set_expected_responses([ proto.ButtonRequest( code=proto_types.ButtonRequest_Address), cosmos_proto.CosmosAddress(address=expected) ]) self.assertEquals( expected, self.client.cosmos_get_address(path, show_display=True)) with self.client: self.client.set_expected_responses( [cosmos_proto.CosmosAddress(address=expected)]) self.assertEquals( expected, self.client.cosmos_get_address(path, show_display=False))
def test_entropy(self): for l in [0, 1, 2, 3, 4, 5, 8, 9, 16, 17, 32, 33, 64, 65, 128, 129, 256, 257, 512, 513, 1024]: with self.client: self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_GetEntropy), proto.Entropy()]) ent = self.client.get_entropy(l) self.assertTrue(len(ent) >= l) print('entropy = ', entropy(ent))
def test_block_4(self): # https://www.nanode.co/block/32ac7d8f5a16a498abf203b8dfee623c9e111ff25e7339f8cd69ec7492b23edd self.setup_mnemonic_nopin_nopassphrase() with self.client: self.client.set_expected_responses([ proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto_nano.NanoSignedTx(), ]) res = self.client.nano_sign_tx( 'Nano', NANO_ACCOUNT_0_PATH, grandparent_hash=unhexlify( '2568bf76336f7a415ca236dab97c1df9de951ca057a2e79df1322e647a259e7b' ), parent_link=unhexlify( 'd7384845d2ae530b45a5dd50ee50757f988329f652781767af3f1bc2322f52b9' ), parent_representative=REP_NANODE, parent_balance=196242336390000000000000000000, link_recipient=RECIPIENT_DONATIONS, representative=REP_NANODE, balance=126242336390000000000000000000, ) self.assertIsInstance(res, proto_nano.NanoSignedTx) self.assertEqual( hexlify(res.block_hash), '32ac7d8f5a16a498abf203b8dfee623c9e111ff25e7339f8cd69ec7492b23edd' ) self.assertEqual( hexlify(res.signature), 'bcb806e140c9e2bc71c51ebbd941b4d99cee3d97fd50e3006eabc5e325c712662e2dc163ee32660875d67815ce4721e122389d2e64f1c9ad4555a9d3d8c33802' )
def test_wipe_device(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.set_expected_responses([proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.wipe_device()
def test_block_1(self): # https://www.nanode.co/block/f9a323153daefe041efb94d69b9669c882c935530ed953bbe8a665dfedda9696 self.setup_mnemonic_nopin_nopassphrase() with self.client: self.client.set_expected_responses([ proto.ButtonRequest( code=proto_types.ButtonRequest_ConfirmOutput), proto_nano.NanoSignedTx(), ]) res = self.client.nano_sign_tx( 'Nano', NANO_ACCOUNT_0_PATH, link_hash=unhexlify( '491fca2c69a84607d374aaf1f6acd3ce70744c5be0721b5ed394653e85233507' ), representative=REP_OFFICIAL_1, balance=96242336390000000000000000000, ) self.assertIsInstance(res, proto_nano.NanoSignedTx) self.assertEqual( hexlify(res.block_hash), 'f9a323153daefe041efb94d69b9669c882c935530ed953bbe8a665dfedda9696' ) self.assertEqual( hexlify(res.signature), 'd247f6b90383b24e612569c75a12f11242f6e03b4914eadc7d941577dcf54a3a7cb7f0a4aba4246a40d9ebb5ee1e00b4a0a834ad5a1e7bef24e11f62b95a9e09' )
def test_testnet_one_two_fee(self): self.setup_mnemonic_allallall() # see 87be0736f202f7c2bff0781b42bad3e0cdcb54761939da69ea793a3735552c56 # tx: e5040e1bc1ae7667ffb9e5248e90b2fb93cd9150234151ce90e14ab2f5933bcd # input 0: 0.31 BTC inp1 = proto_types.TxInputType( address_n=parse_path("44'/1'/0'/0/0"), # amount=31000000, prev_hash=TXHASH_e5040e, prev_index=0, ) out1 = proto_types.TxOutputType( address='msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', amount=30090000, script_type=proto_types.PAYTOADDRESS, ) out2 = proto_types.TxOutputType( address_n=parse_path("44'/1'/0'/1/0"), amount=900000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_tx_api(tx_api.TxApiTestnet) self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=TXHASH_e5040e)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_e5040e)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_e5040e)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_e5040e)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1, ], [out1, out2]) self.assertEqual(binascii.hexlify(serialized_tx), b'0100000001cd3b93f5b24ae190ce5141235091cd93fbb2908e24e5b9ff6776aec11b0e04e5000000006b483045022100eba3bbcbb82ab1ebac88a394e8fb53b0263dadbb3e8072f0a21ee62818c911060220686a9b7f306d028b54a228b5c47cc6c27b1d01a3b0770440bcc64d55d8bace2c0121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff021023cb01000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288aca0bb0d00000000001976a9143d3cca567e00a04819742b21a696a67da796498b88ac00000000')
def test_testnet_fee_too_high(self): self.setup_mnemonic_nopin_nopassphrase() # tx: 6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54 # input 1: 10.00000000 BTC inp1 = proto_types.TxInputType(address_n=[0], # mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL # amount=1000000000, prev_hash=binascii.unhexlify('6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54'), prev_index=1, ) out1 = proto_types.TxOutputType(address='mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV', amount=1000000000 - 500000000 - 100000000, script_type=proto_types.PAYTOADDRESS, ) out2 = proto_types.TxOutputType(address_n=[2], amount=500000000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_tx_api(tx_api.TxApiTestnet) self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_FeeOverThreshold), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1, ], [out1, out2]) self.assertEqual(binascii.hexlify(serialized_tx), '0100000001549d2977998f899a63c0a9da30dedb2841e33fef561097b05822eccbc7f3906f010000006a47304402205ea68e9d52d4be14420ccecf7f2e11489d49b86bedb79ee99b5e9b7188884150022056219cb3384a5df8048cca286a9533403dbda1571afd84b51379cdaee6a6dea80121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff020084d717000000001976a9140223b1a09138753c9cb0baf95a0a62c82711567a88ac0065cd1d000000001976a9142db345c36563122e2fd0f5485fb7ea9bbf7cb5a288ac00000000')
def test_testnet_one_two_fee(self): self.setup_mnemonic_nopin_nopassphrase() # tx: 6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54 # input 1: 10.00000000 BTC inp1 = proto_types.TxInputType(address_n=[0], # mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL # amount=1000000000, prev_hash=binascii.unhexlify('6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54'), prev_index=1, ) out1 = proto_types.TxOutputType(address='mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV', amount=1000000000 - 500000000 - 10000000, script_type=proto_types.PAYTOADDRESS, ) out2 = proto_types.TxOutputType(address_n=[2], amount=500000000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_tx_api(tx_api.TxApiTestnet) self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("6f90f3c7cbec2258b0971056ef3fe34128dbde30daa9c0639a898f9977299d54"))), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_FeeOverThreshold), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1, ], [out1, out2]) self.assertEqual(binascii.hexlify(serialized_tx), '0100000001549d2977998f899a63c0a9da30dedb2841e33fef561097b05822eccbc7f3906f010000006b4830450221009c2d30385519fdb13dce13d5ac038be07d7b2dad0b0f7b2c1c339d7255bcf553022056a2f5bceab3cd0ffed4d388387e631f419d67ff9ce7798e3d7dfe6a6d6ec4bd0121023230848585885f63803a0a8aecdd6538792d5c539215c91698e315bf0253b43dffffffff0280ce341d000000001976a9140223b1a09138753c9cb0baf95a0a62c82711567a88ac0065cd1d000000001976a9142db345c36563122e2fd0f5485fb7ea9bbf7cb5a288ac00000000')
def test_one_two_fee(self): self.setup_mnemonic_allallall() # tx: c275c333fd1b36bef4af316226c66a8b3693fbfcc081a5e16a2ae5fcb09e92bf inp1 = proto_types.TxInputType( address_n=parse_path("m/44'/0'/0'/0/5"), # 1GA9u9TfCG7SWmKCveBumdA1TZpfom6ZdJ # amount=50000, prev_hash=TXHASH_50f6f1, prev_index=1, ) out1 = proto_types.TxOutputType( address_n=parse_path("m/44'/0'/0'/1/3"), # 1EcL6AyfQTyWKGvXwNSfsWoYnD3whzVFdu amount=30000, script_type=proto_types.PAYTOADDRESS, ) out2 = proto_types.TxOutputType( address='1Up15Msx4sbvUCGm8Xgo2Zp5FQim3wE59', amount=10000, script_type=proto_types.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=TXHASH_50f6f1)), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_50f6f1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_50f6f1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_50f6f1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput), proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx), proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)), proto.TxRequest(request_type=proto_types.TXFINISHED), ]) (signatures, serialized_tx) = self.client.sign_tx('Bitcoin', [inp1, ], [out1, out2]) self.assertEqual(binascii.hexlify(serialized_tx), b'01000000016d20f69067ad1ffd50ee7c0f377dde2c932ccb03e84b5659732da99c20f1f650010000006a47304402203429bd3ce7b38c5c1e8a15340edd79ced41a2939aae62e259d2e3d18e0c5ee7602201b83b10ebc4d6dcee3f9eb42ba8f1ef8a059a05397e0c1b9223d1565a3e6ec01012102a7a079c1ef9916b289c2ff21a992c808d0de3dfcf8a9f163205c5c9e21f55d5cffffffff0230750000000000001976a914954820f1de627a703596ac0396f986d958e3de4c88ac10270000000000001976a91405427736705cfbfaff76b1cff48283707fb1037088ac00000000')