From 8d296ed4c14b084d3fafc869dbd4a18e8e3664b5 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Thu, 22 Mar 2018 15:27:43 +0100 Subject: [PATCH 01/57] tests: add T2 RecoveryDevice test --- .../test_msg_recoverydevice_t2.py | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 trezorlib/tests/device_tests/test_msg_recoverydevice_t2.py diff --git a/trezorlib/tests/device_tests/test_msg_recoverydevice_t2.py b/trezorlib/tests/device_tests/test_msg_recoverydevice_t2.py new file mode 100644 index 0000000000..88240219a3 --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_recoverydevice_t2.py @@ -0,0 +1,105 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2012-2016 Marek Palatinus +# Copyright (C) 2012-2016 Pavol Rusnak +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from __future__ import print_function + +import time + +from .common import * +from trezorlib import messages as proto + + +@pytest.mark.skip_t1 +class TestMsgRecoverydeviceT2(TrezorTest): + + def test_pin_passphrase(self): + mnemonic = self.mnemonic12.split(' ') + ret = self.client.call_raw(proto.RecoveryDevice( + passphrase_protection=True, + pin_protection=True, + label='label', + enforce_wordlist=True)) + + # Enter word count + assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.MnemonicWordCount) + self.client.debug.input(str(len(mnemonic))) + ret = self.client.call_raw(proto.ButtonAck()) + + # Enter mnemonic words + assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.MnemonicInput) + self.client.transport.write(proto.ButtonAck()) + for word in mnemonic: + time.sleep(1) + self.client.debug.input(word) + ret = self.client.transport.read() + + # Enter PIN for first time + assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.Other) + self.client.debug.input('654') + ret = self.client.call_raw(proto.ButtonAck()) + + # Enter PIN for second time + assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.Other) + self.client.debug.input('654') + ret = self.client.call_raw(proto.ButtonAck()) + + # Workflow succesfully ended + assert ret == proto.Success(message='Device recovered') + + # Mnemonic is the same + self.client.init_device() + assert self.client.debug.read_mnemonic() == self.mnemonic12 + + assert self.client.features.pin_protection is True + assert self.client.features.passphrase_protection is True + + def test_nopin_nopassphrase(self): + mnemonic = self.mnemonic12.split(' ') + ret = self.client.call_raw(proto.RecoveryDevice( + passphrase_protection=False, + pin_protection=False, + label='label', + enforce_wordlist=True)) + + # Enter word count + assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.MnemonicWordCount) + self.client.debug.input(str(len(mnemonic))) + ret = self.client.call_raw(proto.ButtonAck()) + + # Enter mnemonic words + assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.MnemonicInput) + self.client.transport.write(proto.ButtonAck()) + for word in mnemonic: + time.sleep(1) + self.client.debug.input(word) + ret = self.client.transport.read() + + # Workflow succesfully ended + assert ret == proto.Success(message='Device recovered') + + # Mnemonic is the same + self.client.init_device() + assert self.client.debug.read_mnemonic() == self.mnemonic12 + + assert self.client.features.pin_protection is False + assert self.client.features.passphrase_protection is False + + def test_already_initialized(self): + self.setup_mnemonic_nopin_nopassphrase() + with pytest.raises(Exception): + self.client.recovery_device(12, False, False, 'label', 'english') From c4dc6e2c93aedfd053ff60afe3d86a7bddd4daf8 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Tue, 27 Mar 2018 16:06:49 +0200 Subject: [PATCH 02/57] tests/device/nem: constants used --- trezorlib/tests/device_tests/test_msg_nem_signtx.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index cec01124d0..125c504ba6 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -19,6 +19,8 @@ from .common import * from trezorlib import messages as proto +NEM_TRANSACTION_TYPE_TRANSFER = 0x0101 + # assertion data from T1 @pytest.mark.skip_t2 @@ -48,7 +50,7 @@ class TestMsgNEMSigntx(TrezorTest): "amount": 2000000, "fee": 2000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "type": 257, + "type": NEM_TRANSACTION_TYPE_TRANSFER, "deadline": 74735615, "message": { "payload": hexlify(b"test_nem_transaction_transfer"), @@ -79,7 +81,7 @@ class TestMsgNEMSigntx(TrezorTest): "amount": 2000000, "fee": 2000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "type": 257, + "type": NEM_TRANSACTION_TYPE_TRANSFER, "deadline": 74735615, "message": { # plain text is 32B long => cipher text is 48B @@ -119,7 +121,7 @@ class TestMsgNEMSigntx(TrezorTest): "amount": 1000000, "fee": 1000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "type": 257, + "type": NEM_TRANSACTION_TYPE_TRANSFER, "deadline": 76895615, "version": (0x98 << 24), "message": { From 5d0b5632b3eeae76e6bbd2f1567cf5bb795acd86 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Tue, 27 Mar 2018 16:41:13 +0200 Subject: [PATCH 03/57] nem: missing return fix --- trezorlib/nem.py | 1 + 1 file changed, 1 insertion(+) diff --git a/trezorlib/nem.py b/trezorlib/nem.py index df7cb9c765..9e98bc0261 100644 --- a/trezorlib/nem.py +++ b/trezorlib/nem.py @@ -68,6 +68,7 @@ def create_provision_namespace(transaction): msg.sink = transaction["rentalFeeSink"] msg.fee = transaction["rentalFee"] + return msg def create_mosaic_creation(transaction): From bd3d014dd4b2e9c22d15e12273ebfd488edccc8e Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Tue, 27 Mar 2018 15:52:32 +0300 Subject: [PATCH 04/57] Allow specifying 'state' at ProtocolMixin c-tor --- trezorctl | 2 +- trezorlib/client.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/trezorctl b/trezorctl index 115993eea1..b9ad180c26 100755 --- a/trezorctl +++ b/trezorctl @@ -87,7 +87,7 @@ def cli(ctx, path, verbose, is_json): if path is not None: click.echo("Using path: {}".format(path)) sys.exit(1) - return cls(device) + return cls(transport=device) ctx.obj = get_device diff --git a/trezorlib/client.py b/trezorlib/client.py index 68e259ac89..f691818916 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -496,8 +496,9 @@ class ProtocolMixin(object): PRIME_DERIVATION_FLAG = 0x80000000 VENDORS = ('bitcointrezor.com', 'trezor.io') - def __init__(self, *args, **kwargs): + def __init__(self, state=None, *args, **kwargs): super(ProtocolMixin, self).__init__(*args, **kwargs) + self.state = state self.init_device() self.tx_api = None @@ -505,7 +506,10 @@ class ProtocolMixin(object): self.tx_api = tx_api def init_device(self): - self.features = expect(proto.Features)(self.call)(proto.Initialize()) + init_msg = proto.Initialize() + if self.state is not None: + init_msg.state = self.state + self.features = expect(proto.Features)(self.call)(init_msg) if str(self.features.vendor) not in self.VENDORS: raise RuntimeError("Unsupported device") From e79026cb4b9c6108d3205705285a2ed9a679662b Mon Sep 17 00:00:00 2001 From: matejcik Date: Wed, 28 Mar 2018 15:57:50 +0200 Subject: [PATCH 05/57] trezorlib: fix client ctors for `transport` arg This restores the API before PR #241, and makes sure that ctor signature doesn't depend on mixin order. (Mixins will be going away shortly anyway.) --- trezorlib/client.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/trezorlib/client.py b/trezorlib/client.py index f691818916..398f94b3ee 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -1106,12 +1106,15 @@ class ProtocolMixin(object): class TrezorClient(ProtocolMixin, TextUIMixin, BaseClient): - pass + def __init__(self, transport, *args, **kwargs): + super().__init__(transport=transport, *args, **kwargs) class TrezorClientVerbose(ProtocolMixin, TextUIMixin, VerboseWireMixin, BaseClient): - pass + def __init__(self, transport, *args, **kwargs): + super().__init__(transport=transport, *args, **kwargs) class TrezorClientDebugLink(ProtocolMixin, DebugLinkMixin, VerboseWireMixin, BaseClient): - pass + def __init__(self, transport, *args, **kwargs): + super().__init__(transport=transport, *args, **kwargs) From ac51c73365411fa37b968ed02fb65182c1321acd Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Wed, 28 Mar 2018 10:27:28 +0200 Subject: [PATCH 06/57] tests/device/nem: provision_namespace test --- .../tests/device_tests/test_msg_nem_signtx.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index 125c504ba6..09cb5a0a6c 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -20,6 +20,7 @@ from .common import * from trezorlib import messages as proto NEM_TRANSACTION_TYPE_TRANSFER = 0x0101 +NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE = 0x2001 # assertion data from T1 @@ -139,3 +140,33 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000010000001a0000000e000000030000006e656d0300000078656d40420f0000000000' assert tx.signature == signature + + def test_nem_signtx_provision_namespace(self): + + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + # Confirm provision namespace + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + # Confirm fee + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.NEMSignedTx(), + ]) + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE, + "deadline": 74735615, + "message": { + }, + "newPart": "ABCDE", + "rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "rentalFee": 1500, + "parent": None, + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' + assert hexlify(tx.signature) == b'f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d' From 0e108a662f3da257d41461270f16342f424eaf38 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Wed, 28 Mar 2018 12:18:58 +0200 Subject: [PATCH 07/57] tests/device/nem: mosaic_creation basic test --- .../tests/device_tests/test_msg_nem_signtx.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index 09cb5a0a6c..6b4a68e84a 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -21,6 +21,7 @@ from trezorlib import messages as proto NEM_TRANSACTION_TYPE_TRANSFER = 0x0101 NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE = 0x2001 +NEM_TRANSACTION_TYPE_MOSAIC_CREATION = 0x4001 # assertion data from T1 @@ -170,3 +171,46 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.data) == b'01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' assert hexlify(tx.signature) == b'f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d' + + def test_nem_signtx_mosaic_creation(self): + # todo test levy, properties + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + # Confirm mosaic + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + # Confirm mosaic description + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + # Confirm mosaic immutable supply + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + # err in mcu: + # proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + # Confirm final with fee + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.NEMSignedTx(), + ]) + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": NEM_TRANSACTION_TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "levy": {}, + "properties": {}, + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e' From 3248b47e5bddbae1bec73f80565a3fd07d328201 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Wed, 28 Mar 2018 16:23:16 +0200 Subject: [PATCH 08/57] tests/device/nem: mosaic creation properties test --- .../tests/device_tests/test_msg_nem_signtx.py | 63 ++++++++++++++----- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index 6b4a68e84a..c4b435abdb 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -22,6 +22,7 @@ from trezorlib import messages as proto NEM_TRANSACTION_TYPE_TRANSFER = 0x0101 NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE = 0x2001 NEM_TRANSACTION_TYPE_MOSAIC_CREATION = 0x4001 +TYPE_MOSAIC_SUPPLY_CHANGE = 0x4002 # assertion data from T1 @@ -173,23 +174,11 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.signature) == b'f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d' def test_nem_signtx_mosaic_creation(self): - # todo test levy, properties + # todo test levy self.setup_mnemonic_nopin_nopassphrase() with self.client: - self.client.set_expected_responses([ - # Confirm mosaic - proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), - # Confirm mosaic description - proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), - # Confirm mosaic immutable supply - proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), - # err in mcu: - # proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), - # Confirm final with fee - proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), - proto.NEMSignedTx(), - ]) + # todo assert responses, swipe down tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 74649215, @@ -214,3 +203,49 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' assert hexlify(tx.signature) == b'537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e' + + def test_nem_signtx_mosaic_creation_properties(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + # todo assert responses, swipe down + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": NEM_TRANSACTION_TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "levy": {}, + "properties": [ + { + "name": "divisibility", + "value": "4" + }, + { + "name": "initialSupply", + "value": "200" + }, + { + "name": "supplyMutable", + "value": "false" + }, + { + "name": "transferable", + "value": "true" + } + ], + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e' From 48cb8d0216706fbc06c2f0b712c314a15268596a Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Wed, 28 Mar 2018 17:00:49 +0200 Subject: [PATCH 09/57] tests/device/nem: mosaic creation levy test --- .../tests/device_tests/test_msg_nem_signtx.py | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index c4b435abdb..d99652ea43 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -249,3 +249,57 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' assert hexlify(tx.signature) == b'f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e' + + def test_nem_signtx_mosaic_creation_levy(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + # todo assert responses, swipe down + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": NEM_TRANSACTION_TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "properties": [ + { + "name": "divisibility", + "value": "4" + }, + { + "name": "initialSupply", + "value": "200" + }, + { + "name": "supplyMutable", + "value": "false" + }, + { + "name": "transferable", + "value": "true" + } + ], + "levy": { + "type": 1, + "fee": 2, + "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "mosaicId": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + }, + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a' From 326056b96836271914dbed505f05f4b8fa48934f Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Wed, 28 Mar 2018 17:25:53 +0200 Subject: [PATCH 10/57] tests/device/nem: mosaic supply change test; const fixes --- trezorlib/nem.py | 22 +++++----- .../tests/device_tests/test_msg_nem_signtx.py | 40 +++++++++++++++---- trezorlib/tests/unit_tests/test_nem.py | 2 +- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/trezorlib/nem.py b/trezorlib/nem.py index 9e98bc0261..9822c04216 100644 --- a/trezorlib/nem.py +++ b/trezorlib/nem.py @@ -2,13 +2,13 @@ import binascii import json from . import messages as proto -TYPE_MOSAIC_TRANSFER = 0x0101 +TYPE_TRANSACTION_TRANSFER = 0x0101 TYPE_IMPORTANCE_TRANSFER = 0x0801 -TYPE_MULTISIG_CHANGE = 0x1001 -TYPE_MULTISIG_SIGN = 0x1002 -TYPE_MULTISIG_TX = 0x1004 +TYPE_AGGREGATE_MODIFICATION = 0x1001 +TYPE_MULTISIG_SIGNATURE = 0x1002 +TYPE_MULTISIG = 0x1004 TYPE_PROVISION_NAMESPACE = 0x2001 -TYPE_MOSAIC_DEFINITION_CREATION = 0x4001 +TYPE_MOSAIC_CREATION = 0x4001 TYPE_MOSAIC_SUPPLY_CHANGE = 0x4002 @@ -117,24 +117,24 @@ def create_supply_change(transaction): def create_sign_tx(transaction): msg = proto.NEMSignTx() msg.transaction = create_transaction_common(transaction) - msg.cosigning = (transaction["type"] == TYPE_MULTISIG_SIGN) + msg.cosigning = (transaction["type"] == TYPE_MULTISIG_SIGNATURE) - if transaction["type"] in (TYPE_MULTISIG_SIGN, TYPE_MULTISIG_TX): + if transaction["type"] in (TYPE_MULTISIG_SIGNATURE, TYPE_MULTISIG): transaction = transaction["otherTrans"] msg.multisig = create_transaction_common(transaction) elif "otherTrans" in transaction: raise ValueError("Transaction does not support inner transaction") - if transaction["type"] == TYPE_MOSAIC_TRANSFER: + if transaction["type"] == TYPE_TRANSACTION_TRANSFER: msg.transfer = create_transfer(transaction) - elif transaction["type"] == TYPE_MULTISIG_CHANGE: + elif transaction["type"] == TYPE_AGGREGATE_MODIFICATION: msg.aggregate_modification = create_aggregate_modification(transaction) elif transaction["type"] == TYPE_PROVISION_NAMESPACE: msg.provision_namespace = create_provision_namespace(transaction) - elif transaction["type"] == TYPE_MOSAIC_DEFINITION_CREATION: + elif transaction["type"] == TYPE_MOSAIC_CREATION: msg.mosaic_creation = create_mosaic_creation(transaction) elif transaction["type"] == TYPE_MOSAIC_SUPPLY_CHANGE: - msg.mosaic_supply_change = create_supply_change(transaction) + msg.supply_change = create_supply_change(transaction) else: raise ValueError("Unknown transaction type") diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index d99652ea43..adfba2c543 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -18,6 +18,7 @@ from .common import * from trezorlib import messages as proto +from trezorlib import nem NEM_TRANSACTION_TYPE_TRANSFER = 0x0101 NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE = 0x2001 @@ -53,7 +54,7 @@ class TestMsgNEMSigntx(TrezorTest): "amount": 2000000, "fee": 2000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "type": NEM_TRANSACTION_TYPE_TRANSFER, + "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 74735615, "message": { "payload": hexlify(b"test_nem_transaction_transfer"), @@ -84,7 +85,7 @@ class TestMsgNEMSigntx(TrezorTest): "amount": 2000000, "fee": 2000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "type": NEM_TRANSACTION_TYPE_TRANSFER, + "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 74735615, "message": { # plain text is 32B long => cipher text is 48B @@ -124,7 +125,7 @@ class TestMsgNEMSigntx(TrezorTest): "amount": 1000000, "fee": 1000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "type": NEM_TRANSACTION_TYPE_TRANSFER, + "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 76895615, "version": (0x98 << 24), "message": { @@ -159,7 +160,7 @@ class TestMsgNEMSigntx(TrezorTest): tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 74649215, "fee": 2000000, - "type": NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE, + "type": nem.TYPE_PROVISION_NAMESPACE, "deadline": 74735615, "message": { }, @@ -183,7 +184,7 @@ class TestMsgNEMSigntx(TrezorTest): tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 74649215, "fee": 2000000, - "type": NEM_TRANSACTION_TYPE_MOSAIC_CREATION, + "type": nem.TYPE_MOSAIC_CREATION, "deadline": 74735615, "message": { }, @@ -212,7 +213,7 @@ class TestMsgNEMSigntx(TrezorTest): tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 74649215, "fee": 2000000, - "type": NEM_TRANSACTION_TYPE_MOSAIC_CREATION, + "type": nem.TYPE_MOSAIC_CREATION, "deadline": 74735615, "message": { }, @@ -258,7 +259,7 @@ class TestMsgNEMSigntx(TrezorTest): tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 74649215, "fee": 2000000, - "type": NEM_TRANSACTION_TYPE_MOSAIC_CREATION, + "type": nem.TYPE_MOSAIC_CREATION, "deadline": 74735615, "message": { }, @@ -303,3 +304,28 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a' + + def test_nem_signtx_mosaic_supply_change(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_SUPPLY_CHANGE, + "deadline": 74735615, + "message": { + }, + "mosaicId": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "supplyType": 1, + "delta": 1, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000' + assert hexlify(tx.signature) == b'928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a' diff --git a/trezorlib/tests/unit_tests/test_nem.py b/trezorlib/tests/unit_tests/test_nem.py index d3da852b73..2662677c69 100644 --- a/trezorlib/tests/unit_tests/test_nem.py +++ b/trezorlib/tests/unit_tests/test_nem.py @@ -8,7 +8,7 @@ def test_nem_basic(): "amount": 1000000, "fee": 1000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "type": nem.TYPE_MOSAIC_TRANSFER, + "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 76895615, "version": (0x98 << 24), "message": { From 5ce254c5352a6e8d9fcd5bfff54765fe32b915ae Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Thu, 29 Mar 2018 11:46:29 +0200 Subject: [PATCH 11/57] tests/device/nem: aggregate modification test --- .../tests/device_tests/test_msg_nem_signtx.py | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index adfba2c543..f7b90a34b4 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -20,11 +20,6 @@ from .common import * from trezorlib import messages as proto from trezorlib import nem -NEM_TRANSACTION_TYPE_TRANSFER = 0x0101 -NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE = 0x2001 -NEM_TRANSACTION_TYPE_MOSAIC_CREATION = 0x4001 -TYPE_MOSAIC_SUPPLY_CHANGE = 0x4002 - # assertion data from T1 @pytest.mark.skip_t2 @@ -329,3 +324,26 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.data) == b'02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000' assert hexlify(tx.signature) == b'928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a' + + def test_nem_signtx_aggregate_modification(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_AGGREGATE_MODIFICATION, + "deadline": 74735615, + "message": { + }, + "modifications": [ + { + "modificationType": 1, # Add + "cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844" + }, + ], + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'01100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844' + assert hexlify(tx.signature) == b'ed074a4b877e575786785e6e499e428edea28498a06bdaed6557ccdfbfe69087acd6f4b63e9faa6a849e49d405374c12762df2f27d55e4b35c1901850f83650f' From 6935c0ee7d0ab30a5512ce5ab1302ca772416dd7 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Thu, 29 Mar 2018 12:43:54 +0200 Subject: [PATCH 12/57] tests/device/nem: importance transfer test --- trezorlib/nem.py | 9 ++++++++ .../tests/device_tests/test_msg_nem_signtx.py | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/trezorlib/nem.py b/trezorlib/nem.py index 9822c04216..e569be8c25 100644 --- a/trezorlib/nem.py +++ b/trezorlib/nem.py @@ -114,6 +114,13 @@ def create_supply_change(transaction): return msg +def create_importance_transfer(transaction): + msg = proto.NEMImportanceTransfer() + msg.mode = transaction["importanceTransfer"]["mode"] + msg.public_key = binascii.unhexlify(transaction["importanceTransfer"]["publicKey"]) + return msg + + def create_sign_tx(transaction): msg = proto.NEMSignTx() msg.transaction = create_transaction_common(transaction) @@ -135,6 +142,8 @@ def create_sign_tx(transaction): msg.mosaic_creation = create_mosaic_creation(transaction) elif transaction["type"] == TYPE_MOSAIC_SUPPLY_CHANGE: msg.supply_change = create_supply_change(transaction) + elif transaction["type"] == TYPE_IMPORTANCE_TRANSFER: + msg.importance_transfer = create_importance_transfer(transaction) else: raise ValueError("Unknown transaction type") diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index f7b90a34b4..f9c449e353 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -347,3 +347,24 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.data) == b'01100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844' assert hexlify(tx.signature) == b'ed074a4b877e575786785e6e499e428edea28498a06bdaed6557ccdfbfe69087acd6f4b63e9faa6a849e49d405374c12762df2f27d55e4b35c1901850f83650f' + + def test_nem_signtx_importance_transfer(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 12349215, + "fee": 9900, + "type": nem.TYPE_IMPORTANCE_TRANSFER, + "deadline": 99, + "message": { + }, + "importanceTransfer": { + "mode": 1, + "publicKey": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844", + }, + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'01080000010000981f6fbc0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084ac26000000000000630000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844' + assert hexlify(tx.signature) == b'b6d9434ec5df80e65e6e45d7f0f3c579b4adfe8567c42d981b06e8ac368b1aad2b24eebecd5efd41f4497051fca8ea8a5e77636a79afc46ee1a8e0fe9e3ba90b' From 7c08800cb9609fa892b539c8c5ecca7ab62e09c4 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Tue, 3 Apr 2018 13:43:03 +0200 Subject: [PATCH 13/57] tests/device/nem: test files seperated; swiping for t2 --- .../tests/device_tests/test_msg_nem_signtx.py | 232 +----------------- .../test_msg_nem_signtx_mosaics.py | 171 +++++++++++++ .../test_msg_nem_signtx_mosaics_t2.py | 210 ++++++++++++++++ .../device_tests/test_msg_nem_signtx_other.py | 101 ++++++++ 4 files changed, 483 insertions(+), 231 deletions(-) create mode 100644 trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics.py create mode 100644 trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py create mode 100644 trezorlib/tests/device_tests/test_msg_nem_signtx_other.py diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index f9c449e353..62308be1d7 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -23,7 +23,7 @@ from trezorlib import nem # assertion data from T1 @pytest.mark.skip_t2 -class TestMsgNEMSigntx(TrezorTest): +class TestMsgNEMSignTx(TrezorTest): def test_nem_signtx_simple(self): # tx hash: 209368053ac61969b6838ceb7e31badeb622ed6aa42d6c58365c42ad1a11e19d @@ -138,233 +138,3 @@ class TestMsgNEMSigntx(TrezorTest): assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000010000001a0000000e000000030000006e656d0300000078656d40420f0000000000' assert tx.signature == signature - - def test_nem_signtx_provision_namespace(self): - - self.setup_mnemonic_nopin_nopassphrase() - - with self.client: - self.client.set_expected_responses([ - # Confirm provision namespace - proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), - # Confirm fee - proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), - proto.NEMSignedTx(), - ]) - - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, - "type": nem.TYPE_PROVISION_NAMESPACE, - "deadline": 74735615, - "message": { - }, - "newPart": "ABCDE", - "rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "rentalFee": 1500, - "parent": None, - "version": (0x98 << 24), - }) - - assert hexlify(tx.data) == b'01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' - assert hexlify(tx.signature) == b'f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d' - - def test_nem_signtx_mosaic_creation(self): - # todo test levy - self.setup_mnemonic_nopin_nopassphrase() - - with self.client: - # todo assert responses, swipe down - - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, - "type": nem.TYPE_MOSAIC_CREATION, - "deadline": 74735615, - "message": { - }, - "mosaicDefinition": { - "id": { - "namespaceId": "hellom", - "name": "Hello mosaic" - }, - "levy": {}, - "properties": {}, - "description": "lorem" - }, - "version": (0x98 << 24), - "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "creationFee": 1500, - }) - - assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' - assert hexlify(tx.signature) == b'537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e' - - def test_nem_signtx_mosaic_creation_properties(self): - self.setup_mnemonic_nopin_nopassphrase() - - with self.client: - # todo assert responses, swipe down - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, - "type": nem.TYPE_MOSAIC_CREATION, - "deadline": 74735615, - "message": { - }, - "mosaicDefinition": { - "id": { - "namespaceId": "hellom", - "name": "Hello mosaic" - }, - "levy": {}, - "properties": [ - { - "name": "divisibility", - "value": "4" - }, - { - "name": "initialSupply", - "value": "200" - }, - { - "name": "supplyMutable", - "value": "false" - }, - { - "name": "transferable", - "value": "true" - } - ], - "description": "lorem" - }, - "version": (0x98 << 24), - "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "creationFee": 1500, - }) - - assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' - assert hexlify(tx.signature) == b'f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e' - - def test_nem_signtx_mosaic_creation_levy(self): - self.setup_mnemonic_nopin_nopassphrase() - - with self.client: - # todo assert responses, swipe down - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, - "type": nem.TYPE_MOSAIC_CREATION, - "deadline": 74735615, - "message": { - }, - "mosaicDefinition": { - "id": { - "namespaceId": "hellom", - "name": "Hello mosaic" - }, - "properties": [ - { - "name": "divisibility", - "value": "4" - }, - { - "name": "initialSupply", - "value": "200" - }, - { - "name": "supplyMutable", - "value": "false" - }, - { - "name": "transferable", - "value": "true" - } - ], - "levy": { - "type": 1, - "fee": 2, - "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "mosaicId": { - "namespaceId": "hellom", - "name": "Hello mosaic" - }, - }, - "description": "lorem" - }, - "version": (0x98 << 24), - "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "creationFee": 1500, - }) - - assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' - assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a' - - def test_nem_signtx_mosaic_supply_change(self): - self.setup_mnemonic_nopin_nopassphrase() - - with self.client: - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, - "type": nem.TYPE_MOSAIC_SUPPLY_CHANGE, - "deadline": 74735615, - "message": { - }, - "mosaicId": { - "namespaceId": "hellom", - "name": "Hello mosaic" - }, - "supplyType": 1, - "delta": 1, - "version": (0x98 << 24), - "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "creationFee": 1500, - }) - - assert hexlify(tx.data) == b'02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000' - assert hexlify(tx.signature) == b'928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a' - - def test_nem_signtx_aggregate_modification(self): - self.setup_mnemonic_nopin_nopassphrase() - - with self.client: - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, - "type": nem.TYPE_AGGREGATE_MODIFICATION, - "deadline": 74735615, - "message": { - }, - "modifications": [ - { - "modificationType": 1, # Add - "cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844" - }, - ], - "version": (0x98 << 24), - }) - - assert hexlify(tx.data) == b'01100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844' - assert hexlify(tx.signature) == b'ed074a4b877e575786785e6e499e428edea28498a06bdaed6557ccdfbfe69087acd6f4b63e9faa6a849e49d405374c12762df2f27d55e4b35c1901850f83650f' - - def test_nem_signtx_importance_transfer(self): - self.setup_mnemonic_nopin_nopassphrase() - - with self.client: - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 12349215, - "fee": 9900, - "type": nem.TYPE_IMPORTANCE_TRANSFER, - "deadline": 99, - "message": { - }, - "importanceTransfer": { - "mode": 1, - "publicKey": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844", - }, - "version": (0x98 << 24), - }) - - assert hexlify(tx.data) == b'01080000010000981f6fbc0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084ac26000000000000630000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844' - assert hexlify(tx.signature) == b'b6d9434ec5df80e65e6e45d7f0f3c579b4adfe8567c42d981b06e8ac368b1aad2b24eebecd5efd41f4497051fca8ea8a5e77636a79afc46ee1a8e0fe9e3ba90b' diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics.py new file mode 100644 index 0000000000..e9f8836b95 --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics.py @@ -0,0 +1,171 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2017 Saleem Rashid +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * +from trezorlib import nem + + +# assertion data from T1 +@pytest.mark.skip_t2 +class TestMsgNEMSignTxMosaics(TrezorTest): + + def test_nem_signtx_mosaic_supply_change(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_SUPPLY_CHANGE, + "deadline": 74735615, + "message": { + }, + "mosaicId": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "supplyType": 1, + "delta": 1, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000' + assert hexlify(tx.signature) == b'928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a' + + def test_nem_signtx_mosaic_creation(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "levy": {}, + "properties": {}, + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e' + + def test_nem_signtx_mosaic_creation_properties(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "levy": {}, + "properties": [ + { + "name": "divisibility", + "value": "4" + }, + { + "name": "initialSupply", + "value": "200" + }, + { + "name": "supplyMutable", + "value": "false" + }, + { + "name": "transferable", + "value": "true" + } + ], + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e' + + def test_nem_signtx_mosaic_creation_levy(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "properties": [ + { + "name": "divisibility", + "value": "4" + }, + { + "name": "initialSupply", + "value": "200" + }, + { + "name": "supplyMutable", + "value": "false" + }, + { + "name": "transferable", + "value": "true" + } + ], + "levy": { + "type": 1, + "fee": 2, + "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "mosaicId": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + }, + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a' diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py new file mode 100644 index 0000000000..423862fbaf --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py @@ -0,0 +1,210 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2017 Saleem Rashid +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * + +from trezorlib import messages as proto +from trezorlib import nem +import time + + +# assertion data from T1 +@pytest.mark.skip_t1 +@pytest.mark.skip_t2 +class TestMsgNEMSignTxMosaics(TrezorTest): + + def test_nem_signtx_mosaic_supply_change(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_SUPPLY_CHANGE, + "deadline": 74735615, + "message": { + }, + "mosaicId": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "supplyType": 1, + "delta": 1, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + }) + + assert hexlify(tx.data) == b'02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000' + assert hexlify(tx.signature) == b'928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a' + + def test_nem_signtx_mosaic_creation(self): + # todo test levy + self.setup_mnemonic_nopin_nopassphrase() + + test_suite = { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "levy": {}, + "properties": {}, + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + } + + # not using client.nem_sign_tx() because of swiping + tx = self._nem_sign(1, test_suite) + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e' + + def test_nem_signtx_mosaic_creation_properties(self): + self.setup_mnemonic_nopin_nopassphrase() + + test_suite = { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "levy": {}, + "properties": [ + { + "name": "divisibility", + "value": "4" + }, + { + "name": "initialSupply", + "value": "200" + }, + { + "name": "supplyMutable", + "value": "false" + }, + { + "name": "transferable", + "value": "true" + } + ], + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + } + + # not using client.nem_sign_tx() because of swiping + tx = self._nem_sign(2, test_suite) + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e' + + def test_nem_signtx_mosaic_creation_levy(self): + self.setup_mnemonic_nopin_nopassphrase() + + test_suite = { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_CREATION, + "deadline": 74735615, + "message": { + }, + "mosaicDefinition": { + "id": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "properties": [ + { + "name": "divisibility", + "value": "4" + }, + { + "name": "initialSupply", + "value": "200" + }, + { + "name": "supplyMutable", + "value": "false" + }, + { + "name": "transferable", + "value": "true" + } + ], + "levy": { + "type": 1, + "fee": 2, + "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "mosaicId": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + }, + "description": "lorem" + }, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + } + + tx = self._nem_sign(2, test_suite) + assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' + assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a' + + def _nem_sign(self, num_of_swipes, test_suite): + n = self.client.expand_path("m/44'/1'/0'/0'/0'") + n = self.client._convert_prime(n) + msg = nem.create_sign_tx(test_suite) + assert msg.transaction is not None + msg.transaction.address_n = n + + # Sending NEMSignTx message + self.client.transport.write(msg) + ret = self.client.transport.read() + + # Confirm output + assert isinstance(ret, proto.ButtonRequest) + self.client.debug.press_yes() + self.client.transport.write(proto.ButtonAck()) + time.sleep(1) + for i in range(num_of_swipes): + self.client.debug.swipe_down() + time.sleep(1) + self.client.debug.press_yes() + ret = self.client.transport.read() + + # Confirm tx + assert isinstance(ret, proto.ButtonRequest) + self.client.debug.press_yes() + self.client.transport.write(proto.ButtonAck()) + return self.client.transport.read() diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py new file mode 100644 index 0000000000..97109d1b23 --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py @@ -0,0 +1,101 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2017 Saleem Rashid +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * + +from trezorlib import messages as proto +from trezorlib import nem +import time + + +# assertion data from T1 +@pytest.mark.skip_t2 +class TestMsgNEMSignTxOther(TrezorTest): + + def test_nem_signtx_aggregate_modification(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_AGGREGATE_MODIFICATION, + "deadline": 74735615, + "message": { + }, + "modifications": [ + { + "modificationType": 1, # Add + "cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844" + }, + ], + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'01100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844' + assert hexlify(tx.signature) == b'ed074a4b877e575786785e6e499e428edea28498a06bdaed6557ccdfbfe69087acd6f4b63e9faa6a849e49d405374c12762df2f27d55e4b35c1901850f83650f' + + def test_nem_signtx_importance_transfer(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 12349215, + "fee": 9900, + "type": nem.TYPE_IMPORTANCE_TRANSFER, + "deadline": 99, + "message": { + }, + "importanceTransfer": { + "mode": 1, + "publicKey": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844", + }, + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'01080000010000981f6fbc0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084ac26000000000000630000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844' + assert hexlify(tx.signature) == b'b6d9434ec5df80e65e6e45d7f0f3c579b4adfe8567c42d981b06e8ac368b1aad2b24eebecd5efd41f4497051fca8ea8a5e77636a79afc46ee1a8e0fe9e3ba90b' + + def test_nem_signtx_provision_namespace(self): + + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + # Confirm provision namespace + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + # Confirm fee + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.NEMSignedTx(), + ]) + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_PROVISION_NAMESPACE, + "deadline": 74735615, + "message": { + }, + "newPart": "ABCDE", + "rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "rentalFee": 1500, + "parent": None, + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' + assert hexlify(tx.signature) == b'f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d' From 12c58ce3cc7a2fcce5ae80bc6a6775b8b537acd2 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Fri, 30 Mar 2018 14:16:38 +0200 Subject: [PATCH 14/57] transport: inject info about udev rules into io/os exception --- trezorlib/transport/hid.py | 8 +++++++- trezorlib/transport/webusb.py | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/trezorlib/transport/hid.py b/trezorlib/transport/hid.py index 3a6884ca2b..9a47354ab8 100644 --- a/trezorlib/transport/hid.py +++ b/trezorlib/transport/hid.py @@ -19,6 +19,7 @@ import time import hid import os +import sys from ..protocol_v1 import ProtocolV1 from ..protocol_v2 import ProtocolV2 @@ -39,7 +40,12 @@ class HidHandle: def open(self): if self.count == 0: self.handle = hid.device() - self.handle.open_path(self.path) + try: + self.handle.open_path(self.path) + except (IOError, OSError) as e: + if sys.platform.startswith('linux'): + e.args = e.args + ('Do you have udev rules installed? https://github.com/trezor/trezor-common/blob/master/udev/51-trezor.rules', ) + raise e self.handle.set_nonblocking(True) self.count += 1 diff --git a/trezorlib/transport/webusb.py b/trezorlib/transport/webusb.py index 44b5dafb53..b9782f748d 100644 --- a/trezorlib/transport/webusb.py +++ b/trezorlib/transport/webusb.py @@ -20,6 +20,7 @@ import time import os import atexit import usb1 +import sys from ..protocol_v1 import ProtocolV1 from ..protocol_v2 import ProtocolV2 @@ -46,7 +47,11 @@ class WebUsbHandle: if self.count == 0: self.handle = self.device.open() if self.handle is None: - raise Exception('Cannot open device') + if sys.platform.startswith('linux'): + args = ('Do you have udev rules installed? https://github.com/trezor/trezor-common/blob/master/udev/51-trezor.rules', ) + else: + args = () + raise IOError('Cannot open device', *args) self.handle.claimInterface(interface) self.count += 1 From 020b298020944eac2d625846f6956c8db817a176 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 3 Apr 2018 18:55:10 +0200 Subject: [PATCH 15/57] tests/device: autodetect Trezor version and skip the appropriate tests automatically --- trezorlib/tests/device_tests/conftest.py | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 trezorlib/tests/device_tests/conftest.py diff --git a/trezorlib/tests/device_tests/conftest.py b/trezorlib/tests/device_tests/conftest.py new file mode 100644 index 0000000000..6cb9d410a5 --- /dev/null +++ b/trezorlib/tests/device_tests/conftest.py @@ -0,0 +1,34 @@ +import pytest + +from . import common +from trezorlib.client import TrezorClient + + +def device_version(): + device = common.get_device() + if not device: + raise RuntimeError() + client = TrezorClient(device) + if client.features.model == "T": + return 2 + else: + return 1 + + +try: + TREZOR_VERSION = device_version() +except: + raise + TREZOR_VERSION = None + + +def pytest_runtest_setup(item): + ''' + Called for each test item (class, individual tests). + Ensures that 'skip_t2' tests are skipped on T2 + and 'skip_t1' tests are skipped on T1. + ''' + if item.get_marker("skip_t2") and TREZOR_VERSION == 2: + pytest.skip("Test excluded on Trezor T") + if item.get_marker("skip_t1") and TREZOR_VERSION == 1: + pytest.skip("Test excluded on Trezor 1") From a4306a00faccbdc69eeb2ce05234360b7deae509 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 3 Apr 2018 19:24:31 +0200 Subject: [PATCH 16/57] tools: add deserialize_tx.py to decode contents of hex-encoded signed BTC transaction. This code will probably come in handy if/when we implement a microwallet. --- tools/deserialize_tx.py | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100755 tools/deserialize_tx.py diff --git a/tools/deserialize_tx.py b/tools/deserialize_tx.py new file mode 100755 index 0000000000..7d91b36d4d --- /dev/null +++ b/tools/deserialize_tx.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +import binascii +import os +import sys + +try: + import construct as c +except ImportError: + sys.stderr.write("This tool requires Construct. Install it with 'pip install Construct'.\n") + sys.exit(1) + +from construct import this, len_ + +if os.isatty(sys.stdin.fileno()): + tx_hex = input("Enter transaction in hex format: ") +else: + tx_hex = sys.stdin.read().strip() + +tx_bin = binascii.unhexlify(tx_hex) + + +CompactUintStruct = c.Struct( + "base" / c.Int8ul, + "ext" / c.Switch(this.base, {0xfd: c.Int16ul, 0xfe: c.Int32ul, 0xff: c.Int64ul}), +) + + +class CompactUintAdapter(c.Adapter): + def _encode(self, obj, context, path): + if obj < 0xfd: + return {"base": obj} + if obj < 2 ** 16: + return {"base": 0xfd, "ext": obj} + if obj < 2 ** 32: + return {"base": 0xfe, "ext": obj} + if obj < 2 ** 64: + return {"base": 0xff, "ext": obj} + raise ValueError("Value too big for compact uint") + + def _decode(self, obj, context, path): + return obj["ext"] or obj["base"] + + +class ConstFlag(c.Adapter): + def __init__(self, const): + self.const = const + super().__init__(c.Optional(c.Const(const))) + + def _encode(self, obj, context, path): + return self.const if obj else None + + def _decode(self, obj, context, path): + return obj is not None + + +CompactUint = CompactUintAdapter(CompactUintStruct) + +TxInput = c.Struct( + "tx" / c.Bytes(32), + "index" / c.Int32ul, + # TODO coinbase tx + "script" / c.Prefixed(CompactUint, c.GreedyBytes), + "sequence" / c.Int32ul, +) + +TxOutput = c.Struct( + "value" / c.Int64ul, + "pk_script" / c.Prefixed(CompactUint, c.GreedyBytes), +) + +StackItem = c.Prefixed(CompactUint, c.GreedyBytes) +TxInputWitness = c.PrefixedArray(CompactUint, StackItem) + +Transaction = c.Struct( + "version" / c.Int32ul, + "segwit" / ConstFlag(b"\x00\x01"), + "inputs" / c.PrefixedArray(CompactUint, TxInput), + "outputs" / c.PrefixedArray(CompactUint, TxOutput), + "witness" / c.If(this.segwit, TxInputWitness[len_(this.inputs)]), + "lock_time" / c.Int32ul, + c.Terminated, +) + +print(Transaction.parse(tx_bin)) From 51d9a809bc590477658296b5f35a2e21009da6b9 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Wed, 4 Apr 2018 13:18:22 +0200 Subject: [PATCH 17/57] tests: pytest xfail is used instead of skipping --- trezorlib/tests/device_tests/test_msg_nem_getaddress.py | 2 +- trezorlib/tests/device_tests/test_msg_nem_signtx.py | 2 +- trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py | 2 +- trezorlib/tests/device_tests/test_msg_nem_signtx_other.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_nem_getaddress.py b/trezorlib/tests/device_tests/test_msg_nem_getaddress.py index 4c64ff8342..305be56a05 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_getaddress.py +++ b/trezorlib/tests/device_tests/test_msg_nem_getaddress.py @@ -18,7 +18,7 @@ from .common import * -@pytest.mark.skip_t2 +@pytest.mark.xfail # to be removed when nem is merged class TestMsgNEMGetaddress(TrezorTest): def test_nem_getaddress(self): diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx.py index 62308be1d7..0f5b651aff 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx.py @@ -22,7 +22,7 @@ from trezorlib import nem # assertion data from T1 -@pytest.mark.skip_t2 +@pytest.mark.xfail # to be removed when nem is merged class TestMsgNEMSignTx(TrezorTest): def test_nem_signtx_simple(self): diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py index 423862fbaf..5b2da5129d 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py @@ -24,7 +24,7 @@ import time # assertion data from T1 @pytest.mark.skip_t1 -@pytest.mark.skip_t2 +@pytest.mark.xfail # to be removed when nem is merged class TestMsgNEMSignTxMosaics(TrezorTest): def test_nem_signtx_mosaic_supply_change(self): diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py index 97109d1b23..89911b3fa8 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py @@ -23,7 +23,7 @@ import time # assertion data from T1 -@pytest.mark.skip_t2 +@pytest.mark.xfail # to be removed when nem is merged class TestMsgNEMSignTxOther(TrezorTest): def test_nem_signtx_aggregate_modification(self): From 0631a0a5b1f2842a100255dadc0bb932d7c9569d Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Wed, 4 Apr 2018 15:18:21 +0200 Subject: [PATCH 18/57] tests/device/nem: transfer multiple mosaics --- ...ntx.py => test_msg_nem_signtx_transfer.py} | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) rename trezorlib/tests/device_tests/{test_msg_nem_signtx.py => test_msg_nem_signtx_transfer.py} (76%) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_transfer.py similarity index 76% rename from trezorlib/tests/device_tests/test_msg_nem_signtx.py rename to trezorlib/tests/device_tests/test_msg_nem_signtx_transfer.py index 0f5b651aff..5e29829a80 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_transfer.py @@ -138,3 +138,51 @@ class TestMsgNEMSignTx(TrezorTest): assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000010000001a0000000e000000030000006e656d0300000078656d40420f0000000000' assert tx.signature == signature + + def test_nem_signtx_multiple_mosaics(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 76809215, + "amount": 1000000, + "fee": 1000000, + "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "type": nem.TYPE_TRANSACTION_TRANSFER, + "deadline": 76895615, + "version": (0x98 << 24), + "message": { + }, + "mosaics": [ + { + "mosaicId": { + "namespaceId": "nem", + "name": "xem", + }, + "quantity": 1000000, + }, + { + "mosaicId": { + "namespaceId": "abc", + "name": "mosaic", + }, + "quantity": 200, + }, + { + "mosaicId": { + "namespaceId": "nem", + "name": "xem", + }, + "quantity": 30000, + }, + { + "mosaicId": { + "namespaceId": "abc", + "name": "mosaic", + }, + "quantity": 2000000, + }, + ] + }) + + assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000020000001d0000001100000003000000616263060000006d6f7361696348851e00000000001a0000000e000000030000006e656d0300000078656d70b70f0000000000' + assert hexlify(tx.signature) == b'c83dec432a791733a79647a30c4c1bb38b27379768f9164cf5c53473078368f3bd9547049882b41ebb90edd1d4eef618cc0293af85d8166f26f3768a3c0b9802' From e43a62cb03db6189306daa0527aaa6709048d7ce Mon Sep 17 00:00:00 2001 From: Jochen Hoenicke Date: Thu, 5 Apr 2018 11:20:08 +0200 Subject: [PATCH 19/57] Updated unit tests for cashaddr. (#195) --- .../tests/device_tests/test_msg_getaddress.py | 10 +-- .../device_tests/test_msg_signtx_bcash.py | 66 +++++++++++++++---- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_getaddress.py b/trezorlib/tests/device_tests/test_msg_getaddress.py index 2f9f1e3c9f..69a656a282 100644 --- a/trezorlib/tests/device_tests/test_msg_getaddress.py +++ b/trezorlib/tests/device_tests/test_msg_getaddress.py @@ -45,9 +45,9 @@ class TestMsgGetaddress(TrezorTest): def test_bch(self): self.setup_mnemonic_allallall() - assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/0/0")) == '1MH9KKcvdCTY44xVDC2k3fjBbX5Cz29N1q' - assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/0/1")) == '1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3' - assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/1/0")) == '1HADRPJpgqBzThepERpVXNi6qRgiLQRNoE' + assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/0/0")) == 'bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv' + assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/0/1")) == 'bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4' + assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/1/0")) == 'bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw' def test_bch_multisig(self): self.setup_mnemonic_allallall() @@ -62,8 +62,8 @@ class TestMsgGetaddress(TrezorTest): m=2, ) for nr in range(1, 4): - assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/" + str(nr) + "'/0/0"), show_display=(nr == 1), multisig=getmultisig(0, 0)) == '33Ju286QvonBz5N1V754ZekQv4GLJqcc5R' - assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/" + str(nr) + "'/1/0"), show_display=(nr == 1), multisig=getmultisig(1, 0)) == '3CPtPpL5mGAPdxUeUDfm2RNdWoSN9dKpXE' + assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/" + str(nr) + "'/0/0"), show_display=(nr == 1), multisig=getmultisig(0, 0)) == 'bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw' + assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/" + str(nr) + "'/1/0"), show_display=(nr == 1), multisig=getmultisig(1, 0)) == 'bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a' def test_public_ckd(self): self.setup_mnemonic_nopin_nopassphrase() diff --git a/trezorlib/tests/device_tests/test_msg_signtx_bcash.py b/trezorlib/tests/device_tests/test_msg_signtx_bcash.py index 61a27c0dd0..39e7ec0feb 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx_bcash.py +++ b/trezorlib/tests/device_tests/test_msg_signtx_bcash.py @@ -29,7 +29,7 @@ class TestMsgSigntxBch(TrezorTest): self.client.set_tx_api(TxApiBcash) inp1 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/0'/0/0"), - # 1MH9KKcvdCTY44xVDC2k3fjBbX5Cz29N1q + # bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv amount=1995344, prev_hash=unhexlify('bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78'), prev_index=0, @@ -41,7 +41,7 @@ class TestMsgSigntxBch(TrezorTest): script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( - address='1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3', + address='bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4', amount=73452, script_type=proto.OutputScriptType.PAYTOADDRESS, ) @@ -66,7 +66,7 @@ class TestMsgSigntxBch(TrezorTest): self.client.set_tx_api(TxApiBcash) inp1 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/0'/1/0"), - # 1HADRPJpgqBzThepERpVXNi6qRgiLQRNoE + # bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw amount=1896050, prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'), prev_index=0, @@ -74,7 +74,47 @@ class TestMsgSigntxBch(TrezorTest): ) inp2 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/0'/0/1"), - # 1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3 + # bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4 + amount=73452, + prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'), + prev_index=1, + script_type=proto.InputScriptType.SPENDADDRESS, + ) + out1 = proto.TxOutputType( + address='bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4', + amount=1934960, + script_type=proto.OutputScriptType.PAYTOADDRESS, + ) + with self.client: + self.client.set_expected_responses([ + proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)), + proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)), + proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)), + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)), + proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)), + proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)), + proto.TxRequest(request_type=proto.RequestType.TXFINISHED), + ]) + (signatures, serialized_tx) = self.client.sign_tx('Bcash', [inp1, inp2], [out1]) + + assert hexlify(serialized_tx) == b'01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000' + + def test_send_bch_oldaddr(self): + self.setup_mnemonic_allallall() + self.client.set_tx_api(TxApiBcash) + inp1 = proto.TxInputType( + address_n=self.client.expand_path("44'/145'/0'/1/0"), + # bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw + amount=1896050, + prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'), + prev_index=0, + script_type=proto.InputScriptType.SPENDADDRESS, + ) + inp2 = proto.TxInputType( + address_n=self.client.expand_path("44'/145'/0'/0/1"), + # bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4 amount=73452, prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'), prev_index=1, @@ -106,7 +146,7 @@ class TestMsgSigntxBch(TrezorTest): self.client.set_tx_api(TxApiBcash) inp1 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/0'/1/0"), - # 1HADRPJpgqBzThepERpVXNi6qRgiLQRNoE + # bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw amount=300, prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'), prev_index=0, @@ -114,14 +154,14 @@ class TestMsgSigntxBch(TrezorTest): ) inp2 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/0'/0/1"), - # 1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3 + # bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4 amount=70, prev_hash=unhexlify('502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'), prev_index=1, script_type=proto.InputScriptType.SPENDADDRESS, ) out1 = proto.TxOutputType( - address='15pnEDZJo3ycPUamqP3tEDnEju1oW5fBCz', + address='bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4', amount=200, script_type=proto.OutputScriptType.PAYTOADDRESS, ) @@ -192,7 +232,7 @@ class TestMsgSigntxBch(TrezorTest): self.client.set_tx_api(TxApiBcash) inp1 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/1000'/0/0"), - # 1MH9KKcvdCTY44xVDC2k3fjBbX5Cz29N1q + # bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv amount=1995344, prev_hash=unhexlify('bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78'), prev_index=0, @@ -204,7 +244,7 @@ class TestMsgSigntxBch(TrezorTest): script_type=proto.OutputScriptType.PAYTOADDRESS, ) out2 = proto.TxOutputType( - address='1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3', + address='bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4', amount=73452, script_type=proto.OutputScriptType.PAYTOADDRESS, ) @@ -263,7 +303,7 @@ class TestMsgSigntxBch(TrezorTest): inp1 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/1'/1/0"), multisig=getmultisig(1, 0, [b'', sig, b'']), - # 3CPtPpL5mGAPdxUeUDfm2RNdWoSN9dKpXE + # bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a amount=24000, prev_hash=unhexlify('f68caf10df12d5b07a34601d88fa6856c6edcbf4d05ebef3486510ae1c293d5f'), prev_index=1, @@ -311,14 +351,14 @@ class TestMsgSigntxBch(TrezorTest): inp1 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/3'/0/0"), multisig=getmultisig(0, 0), - # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R + # bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw amount=48490, prev_hash=unhexlify('8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0'), prev_index=0, script_type=proto.InputScriptType.SPENDMULTISIG, ) out1 = proto.TxOutputType( - address='113Q5hHQNQ3bc1RpPX6UNw4GAXstyeA3Dk', + address='bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9', amount=24000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) @@ -347,7 +387,7 @@ class TestMsgSigntxBch(TrezorTest): inp1 = proto.TxInputType( address_n=self.client.expand_path("44'/145'/1'/0/0"), multisig=getmultisig(0, 0, [b'', b'', signatures1[0]]), - # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R + # bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw amount=48490, prev_hash=unhexlify('8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0'), prev_index=0, From 24dc617f36eef5cb050dda9f37849ee8e612501e Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Thu, 5 Apr 2018 17:03:36 +0200 Subject: [PATCH 20/57] disable bcash tests for T2 --- trezorlib/tests/device_tests/test_msg_getaddress.py | 2 ++ trezorlib/tests/device_tests/test_msg_signtx_bcash.py | 1 + 2 files changed, 3 insertions(+) diff --git a/trezorlib/tests/device_tests/test_msg_getaddress.py b/trezorlib/tests/device_tests/test_msg_getaddress.py index 69a656a282..e850e0393b 100644 --- a/trezorlib/tests/device_tests/test_msg_getaddress.py +++ b/trezorlib/tests/device_tests/test_msg_getaddress.py @@ -43,12 +43,14 @@ class TestMsgGetaddress(TrezorTest): self.setup_mnemonic_nopin_nopassphrase() assert self.client.get_address('Testnet', [111, 42]) == 'moN6aN6NP1KWgnPSqzrrRPvx2x1UtZJssa' + @pytest.mark.skip_t2 def test_bch(self): self.setup_mnemonic_allallall() assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/0/0")) == 'bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv' assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/0/1")) == 'bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4' assert self.client.get_address('Bcash', self.client.expand_path("44'/145'/0'/1/0")) == 'bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw' + @pytest.mark.skip_t2 def test_bch_multisig(self): self.setup_mnemonic_allallall() xpubs = [] diff --git a/trezorlib/tests/device_tests/test_msg_signtx_bcash.py b/trezorlib/tests/device_tests/test_msg_signtx_bcash.py index 39e7ec0feb..1e29ecf471 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx_bcash.py +++ b/trezorlib/tests/device_tests/test_msg_signtx_bcash.py @@ -22,6 +22,7 @@ from trezorlib.ckd_public import deserialize from trezorlib.client import CallException +@pytest.mark.skip_t2 class TestMsgSigntxBch(TrezorTest): def test_send_bch_change(self): From 891865f948f363686b7cfa158ba7695621fe17a8 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Thu, 5 Apr 2018 16:02:25 +0200 Subject: [PATCH 21/57] tests/device/nem: tests fixes due to layout changes --- .../test_msg_nem_signtx_mosaics_t2.py | 13 +++-- ...other.py => test_msg_nem_signtx_others.py} | 51 ++++++++---------- ...er.py => test_msg_nem_signtx_transfers.py} | 54 ++++++++----------- 3 files changed, 52 insertions(+), 66 deletions(-) rename trezorlib/tests/device_tests/{test_msg_nem_signtx_other.py => test_msg_nem_signtx_others.py} (64%) rename trezorlib/tests/device_tests/{test_msg_nem_signtx_transfer.py => test_msg_nem_signtx_transfers.py} (82%) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py index 5b2da5129d..73d5db4926 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py @@ -53,7 +53,6 @@ class TestMsgNEMSignTxMosaics(TrezorTest): assert hexlify(tx.signature) == b'928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a' def test_nem_signtx_mosaic_creation(self): - # todo test levy self.setup_mnemonic_nopin_nopassphrase() test_suite = { @@ -78,7 +77,7 @@ class TestMsgNEMSignTxMosaics(TrezorTest): } # not using client.nem_sign_tx() because of swiping - tx = self._nem_sign(1, test_suite) + tx = self._nem_sign(2, test_suite) assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' assert hexlify(tx.signature) == b'537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e' @@ -177,7 +176,7 @@ class TestMsgNEMSignTxMosaics(TrezorTest): "creationFee": 1500, } - tx = self._nem_sign(2, test_suite) + tx = self._nem_sign(5, test_suite) assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a' @@ -192,7 +191,7 @@ class TestMsgNEMSignTxMosaics(TrezorTest): self.client.transport.write(msg) ret = self.client.transport.read() - # Confirm output + # Confirm action assert isinstance(ret, proto.ButtonRequest) self.client.debug.press_yes() self.client.transport.write(proto.ButtonAck()) @@ -203,6 +202,12 @@ class TestMsgNEMSignTxMosaics(TrezorTest): self.client.debug.press_yes() ret = self.client.transport.read() + # Confirm action + assert isinstance(ret, proto.ButtonRequest) + self.client.debug.press_yes() + self.client.transport.write(proto.ButtonAck()) + ret = self.client.transport.read() + # Confirm tx assert isinstance(ret, proto.ButtonRequest) self.client.debug.press_yes() diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_others.py similarity index 64% rename from trezorlib/tests/device_tests/test_msg_nem_signtx_other.py rename to trezorlib/tests/device_tests/test_msg_nem_signtx_others.py index 89911b3fa8..2b8206ffc1 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_other.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_others.py @@ -17,9 +17,7 @@ from .common import * -from trezorlib import messages as proto from trezorlib import nem -import time # assertion data from T1 @@ -43,11 +41,13 @@ class TestMsgNEMSignTxOther(TrezorTest): "cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844" }, ], + "minCosignatories": { + "relativeChange": 3 + }, "version": (0x98 << 24), }) - - assert hexlify(tx.data) == b'01100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844' - assert hexlify(tx.signature) == b'ed074a4b877e575786785e6e499e428edea28498a06bdaed6557ccdfbfe69087acd6f4b63e9faa6a849e49d405374c12762df2f27d55e4b35c1901850f83650f' + assert hexlify(tx.data) == b'01100000020000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f878440400000003000000' + assert hexlify(tx.signature) == b'1200e552d8732ce3eae96719731194abfc5a09d98f61bb35684f4eeaeff15b1bdf326ee7b1bbbe89d3f68c8e07ad3daf72e4c7f031094ad2236b97918ad98601' def test_nem_signtx_importance_transfer(self): self.setup_mnemonic_nopin_nopassphrase() @@ -61,7 +61,7 @@ class TestMsgNEMSignTxOther(TrezorTest): "message": { }, "importanceTransfer": { - "mode": 1, + "mode": 1, # activate "publicKey": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844", }, "version": (0x98 << 24), @@ -74,28 +74,19 @@ class TestMsgNEMSignTxOther(TrezorTest): self.setup_mnemonic_nopin_nopassphrase() - with self.client: - self.client.set_expected_responses([ - # Confirm provision namespace - proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), - # Confirm fee - proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), - proto.NEMSignedTx(), - ]) + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_PROVISION_NAMESPACE, + "deadline": 74735615, + "message": { + }, + "newPart": "ABCDE", + "rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "rentalFee": 1500, + "parent": None, + "version": (0x98 << 24), + }) - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, - "type": nem.TYPE_PROVISION_NAMESPACE, - "deadline": 74735615, - "message": { - }, - "newPart": "ABCDE", - "rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "rentalFee": 1500, - "parent": None, - "version": (0x98 << 24), - }) - - assert hexlify(tx.data) == b'01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' - assert hexlify(tx.signature) == b'f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d' + assert hexlify(tx.data) == b'01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' + assert hexlify(tx.signature) == b'f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d' diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_transfer.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py similarity index 82% rename from trezorlib/tests/device_tests/test_msg_nem_signtx_transfer.py rename to trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py index 5e29829a80..dfd079b2ec 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_transfer.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py @@ -32,7 +32,6 @@ class TestMsgNEMSignTx(TrezorTest): ) self.setup_mnemonic_nopin_nopassphrase() - with self.client: self.client.set_expected_responses([ # Confirm transfer and network fee @@ -41,7 +40,7 @@ class TestMsgNEMSignTx(TrezorTest): proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), # Confirm recipient proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), - proto.NEMSignedTx(signature=signature), + proto.NEMSignedTx(), ]) tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { @@ -106,38 +105,29 @@ class TestMsgNEMSignTx(TrezorTest): self.setup_mnemonic_nopin_nopassphrase() - with self.client: - self.client.set_expected_responses([ - # Confirm transfer and network fee - proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), - # Confirm recipient - proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), - proto.NEMSignedTx(signature=signature), - ]) - - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 76809215, - "amount": 1000000, - "fee": 1000000, - "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "type": nem.TYPE_TRANSACTION_TRANSFER, - "deadline": 76895615, - "version": (0x98 << 24), - "message": { - }, - "mosaics": [ - { - "mosaicId": { - "namespaceId": "nem", - "name": "xem", - }, - "quantity": 1000000, + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 76809215, + "amount": 1000000, + "fee": 1000000, + "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "type": nem.TYPE_TRANSACTION_TRANSFER, + "deadline": 76895615, + "version": (0x98 << 24), + "message": { + }, + "mosaics": [ + { + "mosaicId": { + "namespaceId": "nem", + "name": "xem", }, - ], - }) + "quantity": 1000000, + }, + ], + }) - assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000010000001a0000000e000000030000006e656d0300000078656d40420f0000000000' - assert tx.signature == signature + assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000010000001a0000000e000000030000006e656d0300000078656d40420f0000000000' + assert tx.signature == signature def test_nem_signtx_multiple_mosaics(self): self.setup_mnemonic_nopin_nopassphrase() From edbcd2012dfc37c92405246e7baf32868b88b033 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Tue, 10 Apr 2018 14:50:01 +0200 Subject: [PATCH 22/57] tests/device/nem: multisig tests --- trezorlib/nem.py | 2 +- .../test_msg_nem_signtx_multisig.py | 161 ++++++++++++++++++ .../test_msg_nem_signtx_others.py | 25 --- 3 files changed, 162 insertions(+), 26 deletions(-) create mode 100644 trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py diff --git a/trezorlib/nem.py b/trezorlib/nem.py index e569be8c25..19c4f7b3a0 100644 --- a/trezorlib/nem.py +++ b/trezorlib/nem.py @@ -19,7 +19,7 @@ def create_transaction_common(transaction): msg.fee = transaction["fee"] msg.deadline = transaction["deadline"] - if "signed" in transaction: + if "signer" in transaction: msg.signer = binascii.unhexlify(transaction["signer"]) return msg diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py new file mode 100644 index 0000000000..d0066744df --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py @@ -0,0 +1,161 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2017 Saleem Rashid +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * + +from trezorlib import nem + + +# assertion data from T1 +@pytest.mark.xfail # to be removed when nem is merged +class TestMsgNEMSignTxMultisig(TrezorTest): + + def test_nem_signtx_aggregate_modification(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_AGGREGATE_MODIFICATION, + "deadline": 74735615, + "message": { + }, + "modifications": [ + { + "modificationType": 1, # Add + "cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844" + }, + ], + "minCosignatories": { + "relativeChange": 3 + }, + "version": (0x98 << 24), + }) + assert hexlify(tx.data) == b'01100000020000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f878440400000003000000' + assert hexlify(tx.signature) == b'1200e552d8732ce3eae96719731194abfc5a09d98f61bb35684f4eeaeff15b1bdf326ee7b1bbbe89d3f68c8e07ad3daf72e4c7f031094ad2236b97918ad98601' + + def test_nem_signtx_multisig(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MULTISIG, + "deadline": 74735615, + "otherTrans": { # simple transaction transfer + "timeStamp": 74649215, + "amount": 2000000, + "fee": 2000000, + "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "type": nem.TYPE_TRANSACTION_TRANSFER, + "deadline": 74735615, + "message": { + "payload": hexlify(b"test_nem_transaction_transfer"), + "type": 1, + }, + "version": (0x98 << 24), + "signer": 'c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844', + }, + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74049900000001010000010000987f0e730420000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f8784480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572' + assert hexlify(tx.signature) == b'c42e828ec1686ef8f6ee6af0f28bd8468bd5861a61e440889b07b359ccdf61b369295a54102634c9ccab0a577e100183740395031e835c22855dcdeebd328008' + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MULTISIG, + "deadline": 74735615, + "otherTrans": { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_PROVISION_NAMESPACE, + "deadline": 74735615, + "message": { + }, + "newPart": "ABCDE", + "rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "rentalFee": 1500, + "parent": None, + "version": (0x98 << 24), + "signer": 'c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844', + }, + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74047d00000001200000010000987f0e730420000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f8784480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' + assert hexlify(tx.signature) == b'1b67c2c91240ab55bc2762a673d43745bd1e08206b64bd52501ef945d511c73a1b7cf4d6c1d7f97bd31e13a8a2eafce0707b6331d60d0808d5ac4d1e8dba970e' + + def test_nem_signtx_multisig_signer(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MULTISIG_SIGNATURE, + "deadline": 74735615, + "otherTrans": { # simple transaction transfer + "timeStamp": 74649215, + "amount": 2000000, + "fee": 2000000, + "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "type": nem.TYPE_TRANSACTION_TRANSFER, + "deadline": 74735615, + "message": { + "payload": hexlify(b"test_nem_transaction_transfer"), + "type": 1, + }, + "version": (0x98 << 24), + "signer": 'c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844', + }, + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'02100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042400000020000000e03479740771665bdd292df6fc29c9c63e72b0dbcba95ede615614acda979bf328000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32' + assert hexlify(tx.signature) == b'ff731324a2269fd27e103c88a23ef767667a6641e339de3ce84d8cfeed000dcc18f9af1c68b4a12798a312b2e588c7b7174b578c5fc7503e5a5ef15562abed03' + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MULTISIG_SIGNATURE, + "deadline": 74735615, + "otherTrans": { # simple transaction transfer + "timeStamp": 74649215, + "fee": 2000000, + "type": nem.TYPE_MOSAIC_SUPPLY_CHANGE, + "deadline": 74735615, + "message": { + }, + "mosaicId": { + "namespaceId": "hellom", + "name": "Hello mosaic" + }, + "supplyType": 1, + "delta": 1, + "version": (0x98 << 24), + "creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "creationFee": 1500, + "signer": 'c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844', + }, + "version": (0x98 << 24), + }) + + assert hexlify(tx.data) == b'02100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042400000020000000d4773c2daeb338a1f41e1595bcabf7a1d788517235c9796c6fd5e094f1aa474d28000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32' + assert hexlify(tx.signature) == b'9f72079ece8d3bf647da3c09d03e39e94cbc98c525128c5f9cef1d24666b57e1960d95db3199d56435ff9faaf098860248fc8b5d859ddd9049a6f7a5973f320f' + + diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_others.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_others.py index 2b8206ffc1..50812c1fb0 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_others.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_others.py @@ -24,31 +24,6 @@ from trezorlib import nem @pytest.mark.xfail # to be removed when nem is merged class TestMsgNEMSignTxOther(TrezorTest): - def test_nem_signtx_aggregate_modification(self): - self.setup_mnemonic_nopin_nopassphrase() - - with self.client: - tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, - "type": nem.TYPE_AGGREGATE_MODIFICATION, - "deadline": 74735615, - "message": { - }, - "modifications": [ - { - "modificationType": 1, # Add - "cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844" - }, - ], - "minCosignatories": { - "relativeChange": 3 - }, - "version": (0x98 << 24), - }) - assert hexlify(tx.data) == b'01100000020000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f878440400000003000000' - assert hexlify(tx.signature) == b'1200e552d8732ce3eae96719731194abfc5a09d98f61bb35684f4eeaeff15b1bdf326ee7b1bbbe89d3f68c8e07ad3daf72e4c7f031094ad2236b97918ad98601' - def test_nem_signtx_importance_transfer(self): self.setup_mnemonic_nopin_nopassphrase() From f96dfe5dba865f7d1bd4db104ffa23049b0f7798 Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 26 Mar 2018 16:08:32 +0200 Subject: [PATCH 23/57] add submodule trezor-common --- .gitmodules | 3 +++ vendor/trezor-common | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 vendor/trezor-common diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..3680066ef4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vendor/trezor-common"] + path = vendor/trezor-common + url = https://github.com/trezor/trezor-common.git diff --git a/vendor/trezor-common b/vendor/trezor-common new file mode 160000 index 0000000000..66a85673ed --- /dev/null +++ b/vendor/trezor-common @@ -0,0 +1 @@ +Subproject commit 66a85673ed303f2cf48bdb3d027adbc7e8464364 From c844430363f1bcad50038f86fc293120dad2eb62 Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 26 Mar 2018 16:09:09 +0200 Subject: [PATCH 24/57] build: include relevant vendored files in sdist --- MANIFEST.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MANIFEST.in b/MANIFEST.in index c245d1bec6..f053067919 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,5 @@ recursive-include bash_completion.d *.sh include trezorlib/tests/txcache/*.json +include vendor/trezor-common/coins.json +include vendor/trezor-common/protob/*.proto include COPYING From ae0cb0478e2fbddfb64b6bb921020cead92e92d8 Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 26 Mar 2018 16:17:45 +0200 Subject: [PATCH 25/57] build: use trezor-common from submodule --- tools/build_protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_protobuf b/tools/build_protobuf index 04ddc9824b..02c328f337 100755 --- a/tools/build_protobuf +++ b/tools/build_protobuf @@ -5,7 +5,7 @@ cd "$(dirname "$0")" GENPATH="../trezorlib/messages" INDEX="$GENPATH/__init__.py" -PROTO_PATH="../../trezor-common/protob" +PROTO_PATH="../vendor/trezor-common/protob" PROTO_FILES="types messages" PB2_OUT="pb2" From 16b0727b4b9d320a7d28fff45a802f9c2baecdee Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 26 Mar 2018 18:14:42 +0200 Subject: [PATCH 26/57] build: include tools in sdist --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index f053067919..7e82f7c37d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ recursive-include bash_completion.d *.sh +include tools/* include trezorlib/tests/txcache/*.json include vendor/trezor-common/coins.json include vendor/trezor-common/protob/*.proto From 3f35475e7bdad48e5ccad2538a29fccd096a9c4f Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 26 Mar 2018 17:38:49 +0200 Subject: [PATCH 27/57] build: preprocess messages and assets in setup.py This enforces presence of the trezor-common submodule, copies coins.json to the package directory (from where we can install it with bdist) and if possible, regenerates protobuf messages. That currently doesn't work on Windows, because it's a shell script. Also it relies on presence of `protoc` protobuf compiler. Therefore the regeneration step is optional and converted protobuf messages should still be commited to this repo. coins.json, OTOH, is gitignored in trezorlib, and must be copied from trezor-common every time. This works because sdist includes the vendor directory. --- .gitignore | 3 +++ setup.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 452facd367..4c8387bc2a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ docs/_build docs/.docs-build-environment .tox/ .cache/ +.pytest_cache/ + +trezorlib/coins.json diff --git a/setup.py b/setup.py index 4d5f992479..17e76015af 100755 --- a/setup.py +++ b/setup.py @@ -1,5 +1,10 @@ #!/usr/bin/env python3 -from setuptools import setup +import os.path +import shutil +import subprocess + +from setuptools import setup, Command +from setuptools.command.build_py import build_py install_requires = [ 'setuptools>=19.0', @@ -24,6 +29,44 @@ else: from trezorlib import __version__ as VERSION + +class PrebuildCommand(Command): + description = 'update vendored files (coins.json, protobuf messages)' + user_options = [] + + TREZOR_COMMON = os.path.join('vendor', 'trezor-common') + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + # check for existence of the submodule directory + coins_json = os.path.join(self.TREZOR_COMMON, 'coins.json') + if not os.path.exists(coins_json): + raise Exception('trezor-common submodule seems to be missing.\n' + + 'Use "git submodule update --init" to retrieve it.') + + # copy coins.json to the tree + shutil.copy(coins_json, 'trezorlib') + + # regenerate messages + try: + subprocess.check_call(os.path.join(os.getcwd(), 'tools', 'build_protobuf')) + except Exception as e: + print(e) + print("Generating protobuf failed. Maybe you don't have 'protoc', or maybe you are on Windows?") + print("Using pre-generated files.") + + +class CustomBuild(build_py): + def run(self): + self.run_command('prebuild') + super().run() + + setup( name='trezor', version=VERSION, @@ -39,6 +82,9 @@ setup( 'trezorlib.tests.device_tests', 'trezorlib.tests.unit_tests', ], + package_data={ + 'trezorlib': ['coins.json'], + }, scripts=['trezorctl'], install_requires=install_requires, python_requires='>=3.3', @@ -51,4 +97,8 @@ setup( 'Operating System :: MacOS :: MacOS X', 'Programming Language :: Python :: 3 :: Only', ], + cmdclass={ + 'prebuild': PrebuildCommand, + 'build_py': CustomBuild, + }, ) From 04326749f4de7dd1c655bf331c6a080398c429ce Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 26 Mar 2018 18:55:45 +0200 Subject: [PATCH 28/57] build: generate protobuf messages in tempdir This way, if the process fails, the files in trezorlib/messages remain untouched. This is important because "setup.py build" now runs the build_protobuf tool, and it can easily fail on a system without protoc. --- tools/build_protobuf | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/tools/build_protobuf b/tools/build_protobuf index 02c328f337..b216407c6e 100755 --- a/tools/build_protobuf +++ b/tools/build_protobuf @@ -3,30 +3,46 @@ set -e cd "$(dirname "$0")" +# set up paths +INDEX="__init__.py" GENPATH="../trezorlib/messages" -INDEX="$GENPATH/__init__.py" PROTO_PATH="../vendor/trezor-common/protob" PROTO_FILES="types messages" -PB2_OUT="pb2" -rm -f "$GENPATH/[A-Z]*.py" -mkdir -p "$GENPATH" +# set up temporary directory & cleanup +TMPDIR=$(mktemp -d) +function cleanup { + rm -r $TMPDIR +} +trap cleanup EXIT -cat > "$INDEX" << EOF +# set up pb2 outdir +PB2_OUT="$TMPDIR/pb2" +mkdir -p "$PB2_OUT" + +# compile .proto files to python2 modules using google protobuf library +for file in $PROTO_FILES; do + protoc --python_out="$PB2_OUT" -I/usr/include -I"$PROTO_PATH" "$PROTO_PATH/$file.proto" +done + +# create index (__init__.py) +cat > "$TMPDIR/$INDEX" << EOF # Automatically generated by pb2py EOF -mkdir -p "$PB2_OUT" - +# convert google protobuf library to trezor's internal format for file in $PROTO_FILES; do - # Compile .proto files to python2 modules using google protobuf library - protoc --python_out="$PB2_OUT" -I/usr/include -I"$PROTO_PATH" "$PROTO_PATH/$file.proto" + ./pb2py -P "trezorlib.protobuf" -p "$PB2_OUT" -l "$TMPDIR/$INDEX" "$file" "$TMPDIR" done -for file in $PROTO_FILES; do - # Convert google protobuf library to trezor's internal format - ./pb2py -P "trezorlib.protobuf" -p "$PB2_OUT" -l "$INDEX" "$file" "$GENPATH" -done +# ensure $GENPATH exists and is empty of messages +mkdir -p "$GENPATH" +# only remove messages - there could possibly be other files not starting with capital letter +rm -f "$GENPATH"/[A-Z]*.py -rm -rf "$PB2_OUT" +# move generated files to the destination +# (this assumes $INDEX is *.py, otherwise we'd have to add $INDEX separately) +mv "$TMPDIR"/*.py "$GENPATH" + +# the exit trap handles removing the tmp directory From 71129fffbf1f7651991dd889c1b11ce24090fe3c Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 26 Mar 2018 19:00:02 +0200 Subject: [PATCH 29/57] travis: run flake8 as one command also exclude vendor subdir over which we possibly don't have control --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c82b64a02a..ff9a6ccfae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,8 +29,7 @@ install: script: - python setup.py install - - flake8 - - flake8 trezorctl + - flake8 . trezorctl --exclude=vendor - tox notifications: From e3d59eedfb56191579cae6e4e363a94081cc7972 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 3 Apr 2018 20:39:30 +0200 Subject: [PATCH 30/57] tx_api: drop completely unused Smartbit API --- trezorlib/tx_api.py | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/trezorlib/tx_api.py b/trezorlib/tx_api.py index b06e9e7766..cefe505a73 100644 --- a/trezorlib/tx_api.py +++ b/trezorlib/tx_api.py @@ -115,40 +115,6 @@ class TxApiInsight(TxApi): return t -class TxApiSmartbit(TxApi): - - def get_tx(self, txhash): - - data = self.fetch_json('tx', txhash) - - data = data['transaction'] - - t = proto.TransactionType() - t.version = int(data['version']) - t.lock_time = data['locktime'] - - for vin in data['inputs']: - i = t.inputs.add() - if 'coinbase' in vin.keys(): - i.prev_hash = b"\0" * 32 - i.prev_index = 0xffffffff # signed int -1 - i.script_sig = binascii.unhexlify(vin['coinbase']) - i.sequence = vin['sequence'] - - else: - i.prev_hash = binascii.unhexlify(vin['txid']) - i.prev_index = vin['vout'] - i.script_sig = binascii.unhexlify(vin['script_sig']['hex']) - i.sequence = vin['sequence'] - - for vout in data['outputs']: - o = t.bin_outputs.add() - o.amount = int(Decimal(vout['value']) * 100000000) - o.script_pubkey = binascii.unhexlify(vout['script_pub_key']['hex']) - - return t - - class TxApiBlockCypher(TxApi): def __init__(self, network, url, zcash=None): @@ -193,5 +159,4 @@ TxApiBcash = TxApiInsight(network='insight_bcash', url='https://bch-bitcore2.tre TxApiBitcoinGold = TxApiInsight(network='insight_bitcoin_gold', url='https://btg-bitcore2.trezor.io/api/') TxApiDecredTestnet = TxApiInsight(network='insight_decred_testnet', url='https://testnet.decred.org/api/') TxApiDogecoin = TxApiBlockCypher(network='blockcypher_dogecoin', url='https://api.blockcypher.com/v1/doge/main/') -TxApiSegnet = TxApiSmartbit(network='smartbit_segnet', url='https://segnet-api.smartbit.com.au/v1/blockchain/') TxApiMonacoin = TxApiInsight(network='insight_monacoin', url='https://mona.insight.monaco-ex.org/insight-api-monacoin/') From 40ff849228c218ca8ca3ce5eacc3faafdd76a252 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 3 Apr 2018 21:25:07 +0200 Subject: [PATCH 31/57] flake8: make flake8 better and more strict this removes some unused variables and also catches a couple bugs --- .flake8 | 8 +--- .travis.yml | 2 +- tools/signtest.py | 74 ++++++++++++++++----------------- trezorctl | 2 +- trezorlib/client.py | 8 +--- trezorlib/transport/__init__.py | 2 +- trezorlib/transport/udp.py | 1 - 7 files changed, 44 insertions(+), 53 deletions(-) diff --git a/.flake8 b/.flake8 index 52c02f4bfe..a89b939558 100644 --- a/.flake8 +++ b/.flake8 @@ -1,17 +1,13 @@ [flake8] filename = *.py, - trezorctl + ./trezorctl exclude = .tox/, build/, dist/, - trezorlib/*_pb2.py + vendor/, ignore = - # F821 undefined name 'unicode' - F821, - # F841 local variable is assigned to but never used - F841, # F401: module imported but unused F401, # F403: used import * diff --git a/.travis.yml b/.travis.yml index ff9a6ccfae..84d548e0f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ install: script: - python setup.py install - - flake8 . trezorctl --exclude=vendor + - flake8 - tox notifications: diff --git a/tools/signtest.py b/tools/signtest.py index 7ec2f4f5c7..547c3c6953 100755 --- a/tools/signtest.py +++ b/tools/signtest.py @@ -111,7 +111,7 @@ class MyTxApiBitcoin(object): txser = self.serialize_tx(t) txhash = tools.Hash(txser)[::-1] - outi = self.inputs.append( + self.inputs.append( proto_types.TxInputType( address_n=self.client.expand_path("44'/0'/0'/0/%d" % idx), script_type=( @@ -178,42 +178,42 @@ def main(): # Get the first address of first BIP44 account # (should be the same address as shown in wallet.trezor.io) - outputs = [ - proto_types.TxOutputType( - amount=0, - script_type=proto_types.PAYTOADDRESS, - address='p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm' - # op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6') - # address_n=client.expand_path("44'/0'/0'/0/35"), - # address='3PUxV6Cc4udQZQsJhArVUzvvVoKC8ohkAj', - ), - # proto_types.TxOutputType( - # amount=0, - # script_type=proto_types.PAYTOOPRETURN, - # op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6') - # ), - # proto_types.TxOutputType( - # amount= 8120, - # script_type=proto_types.PAYTOADDRESS, - # address_n=client.expand_path("44'/1'/0'/1/0"), - # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ', - # address='14KRxYgFc7Se8j7MDdrK5PTNv8meq4GivK', - # ), - # proto_types.TxOutputType( - # amount= 18684 - 2000, - # script_type=proto_types.PAYTOADDRESS, - # address_n=client.expand_path("44'/0'/0'/0/7"), - # # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ', - # # address='1s9TSqr3PHZdXGrYws59Uaf5SPqavH43z', - # ), - # proto_types.TxOutputType( - # amount= 1000, - # script_type=proto_types.PAYTOADDRESS, - # # address_n=client.expand_path("44'/0'/0'/0/18"), - # # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ', - # # address='1NcMqUvyWv1K3Zxwmx5sqfj7ZEmPCSdJFM', - # ), - ] + # outputs = [ + # proto_types.TxOutputType( + # amount=0, + # script_type=proto_types.PAYTOADDRESS, + # address='p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm' + # # op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6') + # # address_n=client.expand_path("44'/0'/0'/0/35"), + # # address='3PUxV6Cc4udQZQsJhArVUzvvVoKC8ohkAj', + # ), + # proto_types.TxOutputType( + # amount=0, + # script_type=proto_types.PAYTOOPRETURN, + # op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6') + # ), + # proto_types.TxOutputType( + # amount= 8120, + # script_type=proto_types.PAYTOADDRESS, + # address_n=client.expand_path("44'/1'/0'/1/0"), + # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ', + # address='14KRxYgFc7Se8j7MDdrK5PTNv8meq4GivK', + # ), + # proto_types.TxOutputType( + # amount= 18684 - 2000, + # script_type=proto_types.PAYTOADDRESS, + # address_n=client.expand_path("44'/0'/0'/0/7"), + # # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ', + # # address='1s9TSqr3PHZdXGrYws59Uaf5SPqavH43z', + # ), + # proto_types.TxOutputType( + # amount= 1000, + # script_type=proto_types.PAYTOADDRESS, + # # address_n=client.expand_path("44'/0'/0'/0/18"), + # # address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ', + # # address='1NcMqUvyWv1K3Zxwmx5sqfj7ZEmPCSdJFM', + # ), + # ] # (signatures, serialized_tx) = client.sign_tx('Testnet', inputs, outputs) (signatures, serialized_tx) = client.sign_tx('Bitcoin', txstore.get_inputs(), txstore.get_outputs()) diff --git a/trezorctl b/trezorctl index b9ad180c26..d59a6c91fb 100755 --- a/trezorctl +++ b/trezorctl @@ -233,7 +233,7 @@ def set_homescreen(connect, filename): elif filename.endswith('.toif'): img = open(filename, 'rb').read() if img[:8] != b'TOIf\x90\x00\x90\x00': - raise CallException(types.Failure_DataError, 'File is not a TOIF file with size of 144x144') + raise CallException(proto.FailureType.DataError, 'File is not a TOIF file with size of 144x144') else: from PIL import Image im = Image.open(filename) diff --git a/trezorlib/client.py b/trezorlib/client.py index 398f94b3ee..ffded24395 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -42,11 +42,6 @@ from .protobuf import MessageType if sys.version_info.major < 3: raise Exception("Trezorlib does not support Python 2 anymore.") -# try: -# from PIL import Image -# SCREENSHOT = True -# except: -# SCREENSHOT = False SCREENSHOT = False @@ -424,6 +419,7 @@ class DebugLinkMixin(object): def call_raw(self, msg): if SCREENSHOT and self.debug: + from PIL import Image layout = self.debug.read_layout() im = Image.new("RGB", (128, 64)) pix = im.load() @@ -804,7 +800,7 @@ class ProtocolMixin(object): @session def sign_tx(self, coin_name, inputs, outputs, version=None, lock_time=None, debug_processor=None): - start = time.time() + # start = time.time() txes = self._prepare_sign_tx(inputs, outputs) # Prepare and send initial message diff --git a/trezorlib/transport/__init__.py b/trezorlib/transport/__init__.py index b720c2e3d4..e6a4bca13e 100644 --- a/trezorlib/transport/__init__.py +++ b/trezorlib/transport/__init__.py @@ -115,4 +115,4 @@ def get_transport(path=None, prefix_search=False): if transports: return transports[0].find_by_path(path, prefix_search=prefix_search) - raise Exception("Unknown path prefix '%s'" % prefix) + raise Exception("Could not find device by path: {}".format(path)) diff --git a/trezorlib/transport/udp.py b/trezorlib/transport/udp.py index 7bbad169c1..ffcfb250f6 100644 --- a/trezorlib/transport/udp.py +++ b/trezorlib/transport/udp.py @@ -67,7 +67,6 @@ class UdpTransport(Transport): @classmethod def enumerate(cls): - devices = [] default_path = '{}:{}'.format(cls.DEFAULT_HOST, cls.DEFAULT_PORT) try: return [cls._try_path(default_path)] From d7fb363ffb40cfdde2b2e744c4685190cafab7c0 Mon Sep 17 00:00:00 2001 From: matejcik Date: Thu, 5 Apr 2018 12:15:19 +0200 Subject: [PATCH 32/57] build: take an optional argument specifying protobuf output directory --- tools/build_protobuf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/build_protobuf b/tools/build_protobuf index b216407c6e..fd2eb5b69b 100755 --- a/tools/build_protobuf +++ b/tools/build_protobuf @@ -1,11 +1,15 @@ #!/bin/bash set -e +if [ -n "$1" ]; then + OUTDIR=`readlink -f "$1"` +fi + cd "$(dirname "$0")" # set up paths INDEX="__init__.py" -GENPATH="../trezorlib/messages" +GENPATH="${OUTDIR:-../trezorlib/messages}" PROTO_PATH="../vendor/trezor-common/protob" PROTO_FILES="types messages" From b82551ce0d12c4ae9b8999be0d0373d36922d9c2 Mon Sep 17 00:00:00 2001 From: matejcik Date: Thu, 5 Apr 2018 12:15:42 +0200 Subject: [PATCH 33/57] travis: check that generated protobuf messages are identical to the commited ones --- .travis.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.travis.yml b/.travis.yml index 84d548e0f7..71fbff6453 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,10 @@ addons: - libudev-dev - libusb-1.0-0-dev +env: + global: + PROTOBUF_VERSION=3.4.0 + python: - "3.3" - "3.4" @@ -26,8 +30,15 @@ install: - pip install "setuptools>=19.0" - pip install tox-travis - pip install flake8 + # protobuf-related dependencies + - curl -LO "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" + - unzip "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" -d protoc + - export PATH="$(pwd)/protoc/bin:$PATH" + - pip install "protobuf == ${PROTOBUF_VERSION}" script: + # check that generated protobuf messages are identical to in-tree ones + - ./tools/build_protobuf messages.tmp && diff -ur messages.tmp trezorlib/messages && rm -r messages.tmp - python setup.py install - flake8 - tox From 4b0e057d4e91bb987fbc856a6e4452abf8ce02d8 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 10 Apr 2018 11:40:06 +0200 Subject: [PATCH 34/57] docs: contributing info for the new submodule --- README.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.rst b/README.rst index bdf8c781d9..02f75eadab 100644 --- a/README.rst +++ b/README.rst @@ -77,3 +77,23 @@ Example: your PIN is **1234** and TREZOR is displaying the following: === === === You have to enter: **3795** + + +Contributing +------------ + +Python-trezor pulls coins info and protobuf messages from `trezor-common `_ repository. If you are +developing new features for Trezor, you will want to start there. Once your changes are accepted to ``trezor-common``, you can make a PR +against this repository. Don't forget to update the submodule with: + +.. code:: + + git submodule update --init --remote + +Then, rebuild the protobuf messages and get ``coins.json`` by running: + +.. code:: + + python3 setup.py prebuild + +To get support for BTC-like coins, these steps are enough and no further changes to the library are necessary. From c4f38fd7402d82230f684ed5b176ce338c16878b Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 10 Apr 2018 11:40:27 +0200 Subject: [PATCH 35/57] trezor-common: update to version with Decred Testnet API URL --- trezorlib/messages/ApplySettings.py | 1 + vendor/trezor-common | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/trezorlib/messages/ApplySettings.py b/trezorlib/messages/ApplySettings.py index 3d836642a7..fbb776e6ae 100644 --- a/trezorlib/messages/ApplySettings.py +++ b/trezorlib/messages/ApplySettings.py @@ -9,5 +9,6 @@ class ApplySettings(p.MessageType): 3: ('use_passphrase', p.BoolType, 0), 4: ('homescreen', p.BytesType, 0), 5: ('passphrase_source', p.UVarintType, 0), + 6: ('auto_lock_delay_ms', p.UVarintType, 0), } MESSAGE_WIRE_TYPE = 25 diff --git a/vendor/trezor-common b/vendor/trezor-common index 66a85673ed..233456f077 160000 --- a/vendor/trezor-common +++ b/vendor/trezor-common @@ -1 +1 @@ -Subproject commit 66a85673ed303f2cf48bdb3d027adbc7e8464364 +Subproject commit 233456f0774dd31cc10c445313dd429ba1140971 From bd43363b1cbc3d966a9b30747a17f1616c00316e Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 10 Apr 2018 11:42:21 +0200 Subject: [PATCH 36/57] coins: refactor, use data from coins.json instead of hardcoded lists --- trezorctl | 8 +-- trezorlib/client.py | 6 +- trezorlib/coins.py | 68 +++++++++++-------- trezorlib/tests/device_tests/common.py | 5 +- .../tests/device_tests/test_msg_signtx.py | 4 +- .../device_tests/test_msg_signtx_bcash.py | 4 +- .../test_msg_signtx_bitcoin_gold.py | 4 +- .../device_tests/test_msg_signtx_decred.py | 4 +- .../device_tests/test_msg_signtx_segwit.py | 4 +- .../test_msg_signtx_segwit_native.py | 4 +- .../device_tests/test_msg_signtx_zcash.py | 5 +- .../device_tests/test_multisig_change.py | 4 +- trezorlib/tests/unit_tests/test_tx_api.py | 5 +- trezorlib/tx_api.py | 12 ---- 14 files changed, 77 insertions(+), 60 deletions(-) diff --git a/trezorctl b/trezorctl index d59a6c91fb..7c9091a457 100755 --- a/trezorctl +++ b/trezorctl @@ -30,9 +30,9 @@ import sys from trezorlib.client import TrezorClient, TrezorClientVerbose, CallException, format_protobuf from trezorlib.transport import get_transport, enumerate_devices, TransportException +from trezorlib import coins from trezorlib import messages as proto from trezorlib import protobuf -from trezorlib.coins import coins_txapi from trezorlib.ckd_public import PRIME_DERIVATION_FLAG @@ -470,11 +470,11 @@ def get_public_node(connect, coin, address, curve, show_display): @click.pass_obj def sign_tx(connect, coin): client = connect() - if coin in coins_txapi: - txapi = coins_txapi[coin] + if coin in coins.tx_api: + txapi = coins.tx_api[coin] else: click.echo('Coin "%s" is not recognized.' % coin, err=True) - click.echo('Supported coin types: %s' % ', '.join(coins_txapi.keys()), err=True) + click.echo('Supported coin types: %s' % ', '.join(coins.tx_api.keys()), err=True) sys.exit(1) client.set_tx_api(txapi) diff --git a/trezorlib/client.py b/trezorlib/client.py index ffded24395..ae9ae0c840 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -34,7 +34,7 @@ from . import messages as proto from . import tools from . import mapping from . import nem -from .coins import coins_slip44 +from .coins import slip44 from .debuglink import DebugLink from .protobuf import MessageType @@ -530,8 +530,8 @@ class ProtocolMixin(object): n = n[1:] # coin_name/a/b/c => 44'/SLIP44_constant'/a/b/c - if n[0] in coins_slip44: - n = ["44'", "%d'" % coins_slip44[n[0]]] + n[1:] + if n[0] in slip44: + n = ["44'", "%d'" % slip44[n[0]]] + n[1:] path = [] for x in n: diff --git a/trezorlib/coins.py b/trezorlib/coins.py index 4298e0c61b..8a2dbe1f66 100644 --- a/trezorlib/coins.py +++ b/trezorlib/coins.py @@ -1,31 +1,41 @@ -from .tx_api import TxApiBitcoin, TxApiTestnet, TxApiLitecoin, TxApiZcash, TxApiDash, TxApiBcash, TxApiDecredTestnet, TxApiDogecoin, TxApiMonacoin, TxApiBitcoinGold +import os.path +import json -coins_slip44 = { - 'Bitcoin': 0, - 'Testnet': 1, - 'Decred Testnet': 1, - 'Litecoin': 2, - 'Dogecoin': 3, - 'Dash': 5, - 'Namecoin': 7, - 'Monacoin': 22, - 'Decred': 42, - 'Ether': 60, - 'EtherClassic': 61, - 'Zcash': 133, - 'Bcash': 145, - 'Bitcoin Gold': 156, -} +from .tx_api import TxApiInsight, TxApiBlockCypher -coins_txapi = { - 'Bitcoin': TxApiBitcoin, - 'Testnet': TxApiTestnet, - 'Litecoin': TxApiLitecoin, - 'Dash': TxApiDash, - 'Zcash': TxApiZcash, - 'Bcash': TxApiBcash, - 'Decred Testnet': TxApiDecredTestnet, - 'Dogecoin': TxApiDogecoin, - 'Monacoin': TxApiMonacoin, - 'Bitcoin Gold': TxApiBitcoinGold, -} +COINS_JSON = os.path.join(os.path.dirname(__file__), 'coins.json') + + +def _load_coins_json(): + # Load coins.json to local variables + # NOTE: coins.json comes from 'vendor/trezor-common/coins.json', + # which is a git submodule. If you're trying to run trezorlib directly + # from the checkout (or tarball), initialize the submodule with: + # $ git submodule update --init + # and install coins.json with: + # $ python setup.py prebuild + with open(COINS_JSON) as coins_json: + coins_list = json.load(coins_json) + return {coin['coin_name']: coin for coin in coins_list} + + +def _insight_for_coin(coin): + if not coin['bitcore']: + return None + zcash = coin['coin_name'].lower().startswith('zcash') + network = 'insight_{}'.format(coin['coin_name'].lower().replace(' ', '_')) + url = coin['bitcore'][0] + 'api/' + return TxApiInsight(network=network, url=url, zcash=zcash) + + +# exported variables +__all__ = ['by_name', 'slip44', 'tx_api'] + +by_name = _load_coins_json() +slip44 = {name: coin['bip44'] for name, coin in by_name.items()} +tx_api = {name: _insight_for_coin(coin) + for name, coin in by_name.items() + if coin["bitcore"]} + +# fixup for Dogecoin +tx_api['Dogecoin'] = TxApiBlockCypher(network='blockcypher_dogecoin', url='https://api.blockcypher.com/v1/doge/main/') diff --git a/trezorlib/tests/device_tests/common.py b/trezorlib/tests/device_tests/common.py index 0fffb7ae9f..8681d947f6 100644 --- a/trezorlib/tests/device_tests/common.py +++ b/trezorlib/tests/device_tests/common.py @@ -22,9 +22,10 @@ from binascii import hexlify, unhexlify import pytest import os +from trezorlib import coins +from trezorlib import tx_api from trezorlib.client import TrezorClient, TrezorClientDebugLink from trezorlib.transport import get_transport -from trezorlib import tx_api tests_dir = os.path.dirname(os.path.abspath(__file__)) tx_api.cache_dir = os.path.join(tests_dir, '../txcache') @@ -42,7 +43,7 @@ class TrezorTest: debuglink = wirelink.find_debug() self.client = TrezorClientDebugLink(wirelink) self.client.set_debuglink(debuglink) - self.client.set_tx_api(tx_api.TxApiBitcoin) + self.client.set_tx_api(coins.tx_api['Bitcoin']) # self.client.set_buttonwait(3) # 1 2 3 4 5 6 7 8 9 10 11 12 diff --git a/trezorlib/tests/device_tests/test_msg_signtx.py b/trezorlib/tests/device_tests/test_msg_signtx.py index 1237bb3d50..7b92325aa6 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_signtx.py @@ -18,9 +18,11 @@ from .common import * +from trezorlib import coins from trezorlib import messages as proto from trezorlib.client import CallException -from trezorlib.tx_api import TxApiTestnet + +TxApiTestnet = coins.tx_api['Testnet'] TXHASH_157041 = unhexlify('1570416eb4302cf52979afd5e6909e37d8fdd874301f7cc87e547e509cb1caa6') diff --git a/trezorlib/tests/device_tests/test_msg_signtx_bcash.py b/trezorlib/tests/device_tests/test_msg_signtx_bcash.py index 1e29ecf471..f397d5b6ad 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx_bcash.py +++ b/trezorlib/tests/device_tests/test_msg_signtx_bcash.py @@ -16,11 +16,13 @@ # along with this library. If not, see . from .common import * +from trezorlib import coins from trezorlib import messages as proto -from trezorlib.tx_api import TxApiBcash from trezorlib.ckd_public import deserialize from trezorlib.client import CallException +TxApiBcash = coins.tx_api['Bcash'] + @pytest.mark.skip_t2 class TestMsgSigntxBch(TrezorTest): diff --git a/trezorlib/tests/device_tests/test_msg_signtx_bitcoin_gold.py b/trezorlib/tests/device_tests/test_msg_signtx_bitcoin_gold.py index 6f033b8cc0..99b5082c00 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx_bitcoin_gold.py +++ b/trezorlib/tests/device_tests/test_msg_signtx_bitcoin_gold.py @@ -17,11 +17,13 @@ # along with this library. If not, see . from .common import * +from trezorlib import coins from trezorlib import messages as proto -from trezorlib.tx_api import TxApiBitcoinGold from trezorlib.ckd_public import deserialize from trezorlib.client import CallException +TxApiBitcoinGold = coins.tx_api["Bitcoin Gold"] + # All data taken from T1 class TestMsgSigntxBitcoinGold(TrezorTest): diff --git a/trezorlib/tests/device_tests/test_msg_signtx_decred.py b/trezorlib/tests/device_tests/test_msg_signtx_decred.py index 80a183e8be..77b0040a5b 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx_decred.py +++ b/trezorlib/tests/device_tests/test_msg_signtx_decred.py @@ -17,8 +17,10 @@ from .common import * +from trezorlib import coins from trezorlib import messages as proto -from trezorlib.tx_api import TxApiDecredTestnet + +TxApiDecredTestnet = coins.tx_api['Decred Testnet'] TXHASH_e16248 = unhexlify("e16248f0b39a0a0c0e53d6f2f84c2a944f0d50e017a82701e8e02e46e979d5ed") diff --git a/trezorlib/tests/device_tests/test_msg_signtx_segwit.py b/trezorlib/tests/device_tests/test_msg_signtx_segwit.py index 5d35a07cd9..65136c3a3f 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx_segwit.py +++ b/trezorlib/tests/device_tests/test_msg_signtx_segwit.py @@ -17,11 +17,13 @@ from .common import * +from trezorlib import coins from trezorlib import messages as proto -from trezorlib.tx_api import TxApiTestnet from trezorlib.ckd_public import deserialize from trezorlib.client import CallException +TxApiTestnet = coins.tx_api["Testnet"] + class TestMsgSigntxSegwit(TrezorTest): diff --git a/trezorlib/tests/device_tests/test_msg_signtx_segwit_native.py b/trezorlib/tests/device_tests/test_msg_signtx_segwit_native.py index 4c4300aa92..f82f93ff82 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx_segwit_native.py +++ b/trezorlib/tests/device_tests/test_msg_signtx_segwit_native.py @@ -17,10 +17,12 @@ from .common import * +from trezorlib import coins from trezorlib import messages as proto -from trezorlib.tx_api import TxApiTestnet from trezorlib.ckd_public import deserialize +TxApiTestnet = coins.tx_api['Testnet'] + class TestMsgSigntxSegwitNative(TrezorTest): diff --git a/trezorlib/tests/device_tests/test_msg_signtx_zcash.py b/trezorlib/tests/device_tests/test_msg_signtx_zcash.py index e45a01a97a..e4dac926e2 100644 --- a/trezorlib/tests/device_tests/test_msg_signtx_zcash.py +++ b/trezorlib/tests/device_tests/test_msg_signtx_zcash.py @@ -18,8 +18,11 @@ from .common import * + +from trezorlib import coins from trezorlib import messages as proto -from trezorlib.tx_api import TxApiZcash + +TxApiZcash = coins.tx_api["Zcash"] TXHASH_93373e = unhexlify('93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c') diff --git a/trezorlib/tests/device_tests/test_multisig_change.py b/trezorlib/tests/device_tests/test_multisig_change.py index ed9607622f..2d2d1c4dd2 100644 --- a/trezorlib/tests/device_tests/test_multisig_change.py +++ b/trezorlib/tests/device_tests/test_multisig_change.py @@ -19,14 +19,14 @@ from .common import * from trezorlib import messages as proto import trezorlib.ckd_public as bip32 -from trezorlib import tx_api +from trezorlib.coins import tx_api class TestMultisigChange(TrezorTest): def setup_method(self, method): super(TestMultisigChange, self).setup_method(method) - self.client.set_tx_api(tx_api.TxApiTestnet) + self.client.set_tx_api(tx_api['Testnet']) node_ext1 = bip32.deserialize('tpubDADHV9u9Y6gkggintTdMjJE3be58zKNLhpxBQyuEM6Pwx3sN9JVLmMCMN4DNVwL9AKec27z5TaWcWuHzMXiGAtcra5DjwWbvppGX4gaEGVN') # m/1 => 02c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e diff --git a/trezorlib/tests/unit_tests/test_tx_api.py b/trezorlib/tests/unit_tests/test_tx_api.py index 888874dd0d..6111b15d83 100644 --- a/trezorlib/tests/unit_tests/test_tx_api.py +++ b/trezorlib/tests/unit_tests/test_tx_api.py @@ -18,8 +18,11 @@ import os +from trezorlib import coins from trezorlib import tx_api -from trezorlib.tx_api import TxApiBitcoin, TxApiTestnet + +TxApiBitcoin = coins.tx_api['Bitcoin'] +TxApiTestnet = coins.tx_api['Testnet'] tests_dir = os.path.dirname(os.path.abspath(__file__)) diff --git a/trezorlib/tx_api.py b/trezorlib/tx_api.py index cefe505a73..e7e8a02d06 100644 --- a/trezorlib/tx_api.py +++ b/trezorlib/tx_api.py @@ -148,15 +148,3 @@ class TxApiBlockCypher(TxApi): o.script_pubkey = binascii.unhexlify(vout['script']) return t - - -TxApiBitcoin = TxApiInsight(network='insight_bitcoin', url='https://btc-bitcore1.trezor.io/api/') -TxApiTestnet = TxApiInsight(network='insight_testnet', url='https://testnet-bitcore3.trezor.io/api/') -TxApiLitecoin = TxApiInsight(network='insight_litecoin', url='https://ltc-bitcore1.trezor.io/api/') -TxApiDash = TxApiInsight(network='insight_dash', url='https://dash-bitcore1.trezor.io/api/') -TxApiZcash = TxApiInsight(network='insight_zcash', url='https://zec-bitcore1.trezor.io/api/', zcash=True) -TxApiBcash = TxApiInsight(network='insight_bcash', url='https://bch-bitcore2.trezor.io/api/') -TxApiBitcoinGold = TxApiInsight(network='insight_bitcoin_gold', url='https://btg-bitcore2.trezor.io/api/') -TxApiDecredTestnet = TxApiInsight(network='insight_decred_testnet', url='https://testnet.decred.org/api/') -TxApiDogecoin = TxApiBlockCypher(network='blockcypher_dogecoin', url='https://api.blockcypher.com/v1/doge/main/') -TxApiMonacoin = TxApiInsight(network='insight_monacoin', url='https://mona.insight.monaco-ex.org/insight-api-monacoin/') From 928498c6660426ffb831a73ae10e45b9272d8186 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 10 Apr 2018 13:31:45 +0200 Subject: [PATCH 37/57] coins: wrap JSON errors in an ImportError --- trezorlib/coins.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/trezorlib/coins.py b/trezorlib/coins.py index 8a2dbe1f66..13a7b7b298 100644 --- a/trezorlib/coins.py +++ b/trezorlib/coins.py @@ -31,7 +31,11 @@ def _insight_for_coin(coin): # exported variables __all__ = ['by_name', 'slip44', 'tx_api'] -by_name = _load_coins_json() +try: + by_name = _load_coins_json() +except Exception as e: + raise ImportError("Failed to load coins.json. Check your installation.") from e + slip44 = {name: coin['bip44'] for name, coin in by_name.items()} tx_api = {name: _insight_for_coin(coin) for name, coin in by_name.items() From ab62f5db6f1f2a9e1f4d5d1320d48f9f56a66424 Mon Sep 17 00:00:00 2001 From: matejcik Date: Tue, 10 Apr 2018 16:01:22 +0200 Subject: [PATCH 38/57] flake8: delete trailing lines --- trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py index d0066744df..63912388ec 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py @@ -157,5 +157,3 @@ class TestMsgNEMSignTxMultisig(TrezorTest): assert hexlify(tx.data) == b'02100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042400000020000000d4773c2daeb338a1f41e1595bcabf7a1d788517235c9796c6fd5e094f1aa474d28000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32' assert hexlify(tx.signature) == b'9f72079ece8d3bf647da3c09d03e39e94cbc98c525128c5f9cef1d24666b57e1960d95db3199d56435ff9faaf098860248fc8b5d859ddd9049a6f7a5973f320f' - - From 0a10b53e3ab29204fd4a807fc56295b1995508f9 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Tue, 13 Mar 2018 15:53:57 +0200 Subject: [PATCH 39/57] client: allow setting auto-lock delay --- trezorctl | 17 +++++++++++++++++ trezorlib/client.py | 4 +++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/trezorctl b/trezorctl index 7c9091a457..6529307c03 100755 --- a/trezorctl +++ b/trezorctl @@ -210,6 +210,23 @@ def set_passphrase_source(connect, source): return connect().apply_settings(passphrase_source=source) +@cli.command(help='Set auto-lock delay (in seconds).') +@click.argument('delay', type=str) +@click.pass_obj +def set_auto_lock_delay(connect, delay): + value, unit = delay[:-1], delay[-1:] + units = { + 's': 1, + 'm': 60, + 'h': 3600, + } + if unit in units: + seconds = float(value) * units[unit] + else: + seconds = float(delay) # assume seconds if no unit is specified + return connect().apply_settings(auto_lock_delay_ms=int(seconds * 1000)) + + @cli.command(help='Set device flags.') @click.argument('flags') @click.pass_obj diff --git a/trezorlib/client.py b/trezorlib/client.py index ae9ae0c840..9b995f86db 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -643,7 +643,7 @@ class ProtocolMixin(object): @field('message') @expect(proto.Success) - def apply_settings(self, label=None, language=None, use_passphrase=None, homescreen=None, passphrase_source=None): + def apply_settings(self, label=None, language=None, use_passphrase=None, homescreen=None, passphrase_source=None, auto_lock_delay_ms=None): settings = proto.ApplySettings() if label is not None: settings.label = label @@ -655,6 +655,8 @@ class ProtocolMixin(object): settings.homescreen = homescreen if passphrase_source is not None: settings.passphrase_source = passphrase_source + if auto_lock_delay_ms is not None: + settings.auto_lock_delay_ms = auto_lock_delay_ms out = self.call(settings) self.init_device() # Reload Features From 892eb4183701038bea81b2485fbc389f19b9a18a Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Tue, 10 Apr 2018 22:17:07 +0300 Subject: [PATCH 40/57] tests: add device test for auto-lock delay --- .../device_tests/test_msg_applysettings.py | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/trezorlib/tests/device_tests/test_msg_applysettings.py b/trezorlib/tests/device_tests/test_msg_applysettings.py index cf57378fe0..07bf805d47 100644 --- a/trezorlib/tests/device_tests/test_msg_applysettings.py +++ b/trezorlib/tests/device_tests/test_msg_applysettings.py @@ -18,6 +18,7 @@ from .common import * +import time from trezorlib import messages as proto @@ -96,3 +97,60 @@ class TestMsgApplysettings(TrezorTest): proto.Success(), proto.Features()]) self.client.apply_settings(homescreen=img) + + @pytest.mark.skip_t2 + def test_apply_auto_lock_delay(self): + self.setup_mnemonic_pin_passphrase() + + with self.client: + self.client.set_expected_responses([proto.PinMatrixRequest(), + proto.ButtonRequest(), + proto.Success(), + proto.Features()]) + self.client.apply_settings(auto_lock_delay_ms=int(10e3)) # 10 secs + + time.sleep(0.1) # sleep less than auto-lock delay + with self.client: + # No PIN protection is required. + self.client.set_expected_responses([proto.Success()]) + self.client.ping(msg='', pin_protection=True) + + time.sleep(10.1) # sleep more than auto-lock delay + with self.client: + self.client.set_expected_responses([proto.PinMatrixRequest(), + proto.Success()]) + self.client.ping(msg='', pin_protection=True) + + @pytest.mark.skip_t2 + def test_apply_minimal_auto_lock_delay(self): + """ + Verify that the delay is not below the minimal auto-lock delay (10 secs) + otherwise the device may auto-lock before any user interaction. + """ + self.setup_mnemonic_pin_passphrase() + + with self.client: + self.client.set_expected_responses([proto.PinMatrixRequest(), + proto.ButtonRequest(), + proto.Success(), + proto.Features()]) + # Note: the actual delay will be 10 secs (see above). + self.client.apply_settings(auto_lock_delay_ms=int(1e3)) + + time.sleep(0.1) # sleep less than auto-lock delay + with self.client: + # No PIN protection is required. + self.client.set_expected_responses([proto.Success()]) + self.client.ping(msg='', pin_protection=True) + + time.sleep(2) # sleep less than the minimal auto-lock delay + with self.client: + # No PIN protection is required. + self.client.set_expected_responses([proto.Success()]) + self.client.ping(msg='', pin_protection=True) + + time.sleep(10.1) # sleep more than the minimal auto-lock delay + with self.client: + self.client.set_expected_responses([proto.PinMatrixRequest(), + proto.Success()]) + self.client.ping(msg='', pin_protection=True) From 497f0467cf8f8293b482173925796507aebe8603 Mon Sep 17 00:00:00 2001 From: Peter van Mourik Date: Wed, 11 Apr 2018 12:24:13 +0200 Subject: [PATCH 41/57] Added Wanchain support (#230) --- trezorctl | 14 ++++++++++---- trezorlib/client.py | 5 ++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/trezorctl b/trezorctl index 6529307c03..a3555434c9 100755 --- a/trezorctl +++ b/trezorctl @@ -714,6 +714,7 @@ def ethereum_get_address(connect, address, show_display): @cli.command(help='Sign (and optionally publish) Ethereum transaction. Use TO as destination address or set TO to "" for contract creation.') @click.option('-a', '--host', default='localhost:8545', help='RPC port of ethereum node for automatic gas/nonce estimation and publishing') @click.option('-c', '--chain-id', type=int, help='EIP-155 chain id (replay protection)') +@click.option('-x', '--tx-type', type=int, help='Wanchain txtype field') @click.option('-n', '--address', required=True, help="BIP-32 path to source address, e.g., m/44'/60'/0'/0/0") @click.option('-v', '--value', default='0', help='Ether amount to transfer, e.g. "100 milliether"') @click.option('-g', '--gas-limit', type=int, help='Gas limit - Required for offline signing') @@ -723,7 +724,7 @@ def ethereum_get_address(connect, address, show_display): @click.option('-p', '--publish', is_flag=True, help='Publish transaction via RPC') @click.argument('to') @click.pass_obj -def ethereum_sign_tx(connect, host, chain_id, address, value, gas_limit, gas_price, nonce, data, publish, to): +def ethereum_sign_tx(connect, host, chain_id, tx_type, address, value, gas_limit, gas_price, nonce, data, publish, to): from ethjsonrpc import EthJsonRpc import rlp @@ -775,7 +776,7 @@ def ethereum_sign_tx(connect, host, chain_id, address, value, gas_limit, gas_pri address_n = client.expand_path(address) address = '0x%s' % (binascii.hexlify(client.ethereum_get_address(address_n)).decode()) - if gas_price is None or gas_limit is None or nonce is None: + if gas_price is None or gas_limit is None or nonce is None or publish: host, port = host.split(':') eth = EthJsonRpc(host, int(port)) @@ -798,6 +799,7 @@ def ethereum_sign_tx(connect, host, chain_id, address, value, gas_limit, gas_pri sig = client.ethereum_sign_tx( n=address_n, + tx_type=tx_type, nonce=nonce, gas_price=gas_price, gas_limit=gas_limit, @@ -806,8 +808,12 @@ def ethereum_sign_tx(connect, host, chain_id, address, value, gas_limit, gas_pri data=data, chain_id=chain_id) - transaction = rlp.encode( - (nonce, gas_price, gas_limit, to_address, value, data) + sig) + if tx_type is None: + transaction = rlp.encode( + (nonce, gas_price, gas_limit, to_address, value, data) + sig) + else: + transaction = rlp.encode( + (tx_type, nonce, gas_price, gas_limit, to_address, value, data) + sig) tx_hex = '0x%s' % binascii.hexlify(transaction).decode() if publish: diff --git a/trezorlib/client.py b/trezorlib/client.py index 9b995f86db..c885d477df 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -572,7 +572,7 @@ class ProtocolMixin(object): return self.call(proto.EthereumGetAddress(address_n=n, show_display=show_display)) @session - def ethereum_sign_tx(self, n, nonce, gas_price, gas_limit, to, value, data=None, chain_id=None): + def ethereum_sign_tx(self, n, nonce, gas_price, gas_limit, to, value, data=None, chain_id=None, tx_type=None): def int_to_big_endian(value): import rlp.utils if value == 0: @@ -599,6 +599,9 @@ class ProtocolMixin(object): if chain_id: msg.chain_id = chain_id + if tx_type is not None: + msg.tx_type = tx_type + response = self.call(msg) while response.data_length is not None: From ff8dafc18232b6237aff23bb4fbcdcbf16b51eda Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Wed, 11 Apr 2018 12:26:53 +0200 Subject: [PATCH 42/57] trezorctl: reorder parameters in ethereum_sign_tx --- trezorctl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trezorctl b/trezorctl index a3555434c9..923cfec745 100755 --- a/trezorctl +++ b/trezorctl @@ -714,7 +714,6 @@ def ethereum_get_address(connect, address, show_display): @cli.command(help='Sign (and optionally publish) Ethereum transaction. Use TO as destination address or set TO to "" for contract creation.') @click.option('-a', '--host', default='localhost:8545', help='RPC port of ethereum node for automatic gas/nonce estimation and publishing') @click.option('-c', '--chain-id', type=int, help='EIP-155 chain id (replay protection)') -@click.option('-x', '--tx-type', type=int, help='Wanchain txtype field') @click.option('-n', '--address', required=True, help="BIP-32 path to source address, e.g., m/44'/60'/0'/0/0") @click.option('-v', '--value', default='0', help='Ether amount to transfer, e.g. "100 milliether"') @click.option('-g', '--gas-limit', type=int, help='Gas limit - Required for offline signing') @@ -722,9 +721,10 @@ def ethereum_get_address(connect, address, show_display): @click.option('-i', '--nonce', type=int, help='Transaction counter - Required for offline signing') @click.option('-d', '--data', default='', help='Data as hex string, e.g. 0x12345678') @click.option('-p', '--publish', is_flag=True, help='Publish transaction via RPC') +@click.option('-x', '--tx-type', type=int, help='TX type (used only for Wanchain)') @click.argument('to') @click.pass_obj -def ethereum_sign_tx(connect, host, chain_id, tx_type, address, value, gas_limit, gas_price, nonce, data, publish, to): +def ethereum_sign_tx(connect, host, chain_id, address, value, gas_limit, gas_price, nonce, data, publish, to, tx_type): from ethjsonrpc import EthJsonRpc import rlp From 767330aea0661929da3f2a1b719275dbfb1ba0e4 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Mon, 16 Apr 2018 12:24:55 +0200 Subject: [PATCH 43/57] tests: multisig fixes --- .../test_msg_nem_signtx_multisig.py | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py index 63912388ec..b41f34ad2b 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_multisig.py @@ -52,17 +52,17 @@ class TestMsgNEMSignTxMultisig(TrezorTest): self.setup_mnemonic_nopin_nopassphrase() tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, + "timeStamp": 1, + "fee": 10000, "type": nem.TYPE_MULTISIG, "deadline": 74735615, "otherTrans": { # simple transaction transfer - "timeStamp": 74649215, + "timeStamp": 2, "amount": 2000000, - "fee": 2000000, + "fee": 15000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "type": nem.TYPE_TRANSACTION_TRANSFER, - "deadline": 74735615, + "deadline": 67890, "message": { "payload": hexlify(b"test_nem_transaction_transfer"), "type": 1, @@ -73,19 +73,19 @@ class TestMsgNEMSignTxMultisig(TrezorTest): "version": (0x98 << 24), }) - assert hexlify(tx.data) == b'04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74049900000001010000010000987f0e730420000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f8784480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572' - assert hexlify(tx.signature) == b'c42e828ec1686ef8f6ee6af0f28bd8468bd5861a61e440889b07b359ccdf61b369295a54102634c9ccab0a577e100183740395031e835c22855dcdeebd328008' + assert hexlify(tx.data) == b'04100000010000980100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841027000000000000ff5f74049900000001010000010000980200000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844983a000000000000320901002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572' + assert hexlify(tx.signature) == b'0cab2fddf2f02b5d7201675b9a71869292fe25ed33a366c7d2cbea7676fed491faaa03310079b7e17884b6ba2e3ea21c4f728d1cca8f190b8288207f6514820a' tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 74649215, - "fee": 2000000, + "fee": 150, "type": nem.TYPE_MULTISIG, - "deadline": 74735615, + "deadline": 789, "otherTrans": { - "timeStamp": 74649215, - "fee": 2000000, + "timeStamp": 123456, + "fee": 2000, "type": nem.TYPE_PROVISION_NAMESPACE, - "deadline": 74735615, + "deadline": 100, "message": { }, "newPart": "ABCDE", @@ -98,24 +98,24 @@ class TestMsgNEMSignTxMultisig(TrezorTest): "version": (0x98 << 24), }) - assert hexlify(tx.data) == b'04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74047d00000001200000010000987f0e730420000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f8784480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' - assert hexlify(tx.signature) == b'1b67c2c91240ab55bc2762a673d43745bd1e08206b64bd52501ef945d511c73a1b7cf4d6c1d7f97bd31e13a8a2eafce0707b6331d60d0808d5ac4d1e8dba970e' + assert hexlify(tx.data) == b'04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620849600000000000000150300007d000000012000000100009840e2010020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844d007000000000000640000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff' + assert hexlify(tx.signature) == b'c915ca3332380925f4050301cdc62269cf29437ac5955321b18da34e570c7fdbb1aec2940a2a553a2a5c90950a4db3c8d3ef899c1a108582e0657f66fbbb0b04' def test_nem_signtx_multisig_signer(self): self.setup_mnemonic_nopin_nopassphrase() tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, + "timeStamp": 333, + "fee": 200, "type": nem.TYPE_MULTISIG_SIGNATURE, - "deadline": 74735615, + "deadline": 444, "otherTrans": { # simple transaction transfer - "timeStamp": 74649215, + "timeStamp": 555, "amount": 2000000, "fee": 2000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "type": nem.TYPE_TRANSACTION_TRANSFER, - "deadline": 74735615, + "deadline": 666, "message": { "payload": hexlify(b"test_nem_transaction_transfer"), "type": 1, @@ -126,19 +126,19 @@ class TestMsgNEMSignTxMultisig(TrezorTest): "version": (0x98 << 24), }) - assert hexlify(tx.data) == b'02100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042400000020000000e03479740771665bdd292df6fc29c9c63e72b0dbcba95ede615614acda979bf328000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32' - assert hexlify(tx.signature) == b'ff731324a2269fd27e103c88a23ef767667a6641e339de3ce84d8cfeed000dcc18f9af1c68b4a12798a312b2e588c7b7174b578c5fc7503e5a5ef15562abed03' + assert hexlify(tx.data) == b'02100000010000984d01000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084c800000000000000bc010000240000002000000087923cd4805f3babe6b5af9cbb2b08be4458e39531618aed73c911f160c8e38528000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32' + assert hexlify(tx.signature) == b'286358a16ae545bff798feab93a713440c7c2f236d52ac0e995669d17a1915b0903667c97fa04418eccb42333cba95b19bccc8ac1faa8224dcfaeb41890ae807' tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { - "timeStamp": 74649215, - "fee": 2000000, + "timeStamp": 900000, + "fee": 200000, "type": nem.TYPE_MULTISIG_SIGNATURE, - "deadline": 74735615, + "deadline": 100, "otherTrans": { # simple transaction transfer - "timeStamp": 74649215, - "fee": 2000000, + "timeStamp": 101111, + "fee": 1000, "type": nem.TYPE_MOSAIC_SUPPLY_CHANGE, - "deadline": 74735615, + "deadline": 13123, "message": { }, "mosaicId": { @@ -155,5 +155,5 @@ class TestMsgNEMSignTxMultisig(TrezorTest): "version": (0x98 << 24), }) - assert hexlify(tx.data) == b'02100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042400000020000000d4773c2daeb338a1f41e1595bcabf7a1d788517235c9796c6fd5e094f1aa474d28000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32' - assert hexlify(tx.signature) == b'9f72079ece8d3bf647da3c09d03e39e94cbc98c525128c5f9cef1d24666b57e1960d95db3199d56435ff9faaf098860248fc8b5d859ddd9049a6f7a5973f320f' + assert hexlify(tx.data) == b'0210000001000098a0bb0d0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084400d030000000000640000002400000020000000c51395626a89a71c1ed785fb5974307a049b3b9e2165d56ed0302fe6b4f02a0128000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32' + assert hexlify(tx.signature) == b'32b1fdf788c4a90c01eedf5972b7709745831d620c13e1e97b0de6481837e162ee551573f2409822754ae940731909ec4b79cf836487e898df476adb10467506' From fd16bbfc8eb3587a530084c3136b665a963b3b85 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Mon, 16 Apr 2018 12:39:17 +0200 Subject: [PATCH 44/57] tests: nem mosaics fix --- trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py index 73d5db4926..9619533985 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_mosaics_t2.py @@ -176,7 +176,7 @@ class TestMsgNEMSignTxMosaics(TrezorTest): "creationFee": 1500, } - tx = self._nem_sign(5, test_suite) + tx = self._nem_sign(6, test_suite) assert hexlify(tx.data) == b'01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000' assert hexlify(tx.signature) == b'b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a' From 9255507529178e8b2c34c8133ea226bc07879e47 Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 16 Apr 2018 17:21:29 +0200 Subject: [PATCH 45/57] tools: update encfs_aes_getpass to work with Py3 probably fixes #169 --- tools/encfs_aes_getpass.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/encfs_aes_getpass.py b/tools/encfs_aes_getpass.py index 64ba603f80..0680ef9559 100755 --- a/tools/encfs_aes_getpass.py +++ b/tools/encfs_aes_getpass.py @@ -98,13 +98,15 @@ def main(): raise ValueError("32 bytes password expected") bip32_path = [10, 0] + sys.stderr.write('Generated password is {}\n'.format(passw)) passw_encrypted = client.encrypt_keyvalue(bip32_path, label, passw, False, True) + sys.stderr.write('Encrypted password is {}\n'.format(passw_encrypted)) data = {'label': label, 'bip32_path': bip32_path, - 'password_encrypted_hex': binascii.hexlify(passw_encrypted)} + 'password_encrypted_hex': binascii.hexlify(passw_encrypted).decode('ascii')} - json.dump(data, open(passw_file, 'wb')) + json.dump(data, open(passw_file, 'w')) # Let's load password data = json.load(open(passw_file, 'r')) @@ -115,6 +117,7 @@ def main(): binascii.unhexlify(data['password_encrypted_hex']), False, True) + sys.stderr.write('Submitting password {}\n'.format(passw)) print(passw) From 688fe06e93a693be23c7fb1bb64f22b1b8873f90 Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 16 Apr 2018 17:29:57 +0200 Subject: [PATCH 46/57] tools: remove forgotten debug statements in encfs_aes_getpass --- tools/encfs_aes_getpass.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/encfs_aes_getpass.py b/tools/encfs_aes_getpass.py index 0680ef9559..4e4b005eda 100755 --- a/tools/encfs_aes_getpass.py +++ b/tools/encfs_aes_getpass.py @@ -98,9 +98,7 @@ def main(): raise ValueError("32 bytes password expected") bip32_path = [10, 0] - sys.stderr.write('Generated password is {}\n'.format(passw)) passw_encrypted = client.encrypt_keyvalue(bip32_path, label, passw, False, True) - sys.stderr.write('Encrypted password is {}\n'.format(passw_encrypted)) data = {'label': label, 'bip32_path': bip32_path, @@ -117,7 +115,6 @@ def main(): binascii.unhexlify(data['password_encrypted_hex']), False, True) - sys.stderr.write('Submitting password {}\n'.format(passw)) print(passw) From c0418333c1cea644cbe327ffb02dd0a7a85a2724 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 16:44:53 +0300 Subject: [PATCH 47/57] common: update trezor-common submodule --- trezorlib/messages/LiskAddress.py | 9 +++++ trezorlib/messages/LiskDelegateType.py | 8 +++++ trezorlib/messages/LiskGetAddress.py | 10 ++++++ trezorlib/messages/LiskGetPublicKey.py | 10 ++++++ trezorlib/messages/LiskMessageSignature.py | 10 ++++++ trezorlib/messages/LiskMultisignatureType.py | 10 ++++++ trezorlib/messages/LiskPublicKey.py | 9 +++++ trezorlib/messages/LiskSignMessage.py | 10 ++++++ trezorlib/messages/LiskSignTx.py | 11 ++++++ trezorlib/messages/LiskSignatureType.py | 8 +++++ trezorlib/messages/LiskSignedTx.py | 9 +++++ trezorlib/messages/LiskTransactionAsset.py | 15 ++++++++ trezorlib/messages/LiskTransactionCommon.py | 17 +++++++++ trezorlib/messages/LiskTransactionType.py | 9 +++++ trezorlib/messages/LiskVerifyMessage.py | 11 ++++++ trezorlib/messages/MessageType.py | 28 +++++++++++++++ trezorlib/messages/StellarAccountMergeOp.py | 10 ++++++ trezorlib/messages/StellarAllowTrustOp.py | 13 +++++++ trezorlib/messages/StellarAssetType.py | 10 ++++++ trezorlib/messages/StellarBumpSequenceOp.py | 10 ++++++ trezorlib/messages/StellarChangeTrustOp.py | 12 +++++++ trezorlib/messages/StellarCreateAccountOp.py | 11 ++++++ .../messages/StellarCreatePassiveOfferOp.py | 15 ++++++++ trezorlib/messages/StellarGetPublicKey.py | 9 +++++ trezorlib/messages/StellarManageDataOp.py | 11 ++++++ trezorlib/messages/StellarManageOfferOp.py | 16 +++++++++ trezorlib/messages/StellarMessageSignature.py | 10 ++++++ trezorlib/messages/StellarPathPaymentOp.py | 16 +++++++++ trezorlib/messages/StellarPaymentOp.py | 13 +++++++ trezorlib/messages/StellarPublicKey.py | 9 +++++ trezorlib/messages/StellarSetOptionsOp.py | 20 +++++++++++ trezorlib/messages/StellarSignMessage.py | 10 ++++++ trezorlib/messages/StellarSignTx.py | 21 +++++++++++ trezorlib/messages/StellarSignedTx.py | 10 ++++++ trezorlib/messages/StellarTxOpRequest.py | 6 ++++ trezorlib/messages/StellarVerifyMessage.py | 11 ++++++ trezorlib/messages/__init__.py | 35 +++++++++++++++++++ vendor/trezor-common | 2 +- 38 files changed, 463 insertions(+), 1 deletion(-) create mode 100644 trezorlib/messages/LiskAddress.py create mode 100644 trezorlib/messages/LiskDelegateType.py create mode 100644 trezorlib/messages/LiskGetAddress.py create mode 100644 trezorlib/messages/LiskGetPublicKey.py create mode 100644 trezorlib/messages/LiskMessageSignature.py create mode 100644 trezorlib/messages/LiskMultisignatureType.py create mode 100644 trezorlib/messages/LiskPublicKey.py create mode 100644 trezorlib/messages/LiskSignMessage.py create mode 100644 trezorlib/messages/LiskSignTx.py create mode 100644 trezorlib/messages/LiskSignatureType.py create mode 100644 trezorlib/messages/LiskSignedTx.py create mode 100644 trezorlib/messages/LiskTransactionAsset.py create mode 100644 trezorlib/messages/LiskTransactionCommon.py create mode 100644 trezorlib/messages/LiskTransactionType.py create mode 100644 trezorlib/messages/LiskVerifyMessage.py create mode 100644 trezorlib/messages/StellarAccountMergeOp.py create mode 100644 trezorlib/messages/StellarAllowTrustOp.py create mode 100644 trezorlib/messages/StellarAssetType.py create mode 100644 trezorlib/messages/StellarBumpSequenceOp.py create mode 100644 trezorlib/messages/StellarChangeTrustOp.py create mode 100644 trezorlib/messages/StellarCreateAccountOp.py create mode 100644 trezorlib/messages/StellarCreatePassiveOfferOp.py create mode 100644 trezorlib/messages/StellarGetPublicKey.py create mode 100644 trezorlib/messages/StellarManageDataOp.py create mode 100644 trezorlib/messages/StellarManageOfferOp.py create mode 100644 trezorlib/messages/StellarMessageSignature.py create mode 100644 trezorlib/messages/StellarPathPaymentOp.py create mode 100644 trezorlib/messages/StellarPaymentOp.py create mode 100644 trezorlib/messages/StellarPublicKey.py create mode 100644 trezorlib/messages/StellarSetOptionsOp.py create mode 100644 trezorlib/messages/StellarSignMessage.py create mode 100644 trezorlib/messages/StellarSignTx.py create mode 100644 trezorlib/messages/StellarSignedTx.py create mode 100644 trezorlib/messages/StellarTxOpRequest.py create mode 100644 trezorlib/messages/StellarVerifyMessage.py diff --git a/trezorlib/messages/LiskAddress.py b/trezorlib/messages/LiskAddress.py new file mode 100644 index 0000000000..a565239fe2 --- /dev/null +++ b/trezorlib/messages/LiskAddress.py @@ -0,0 +1,9 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskAddress(p.MessageType): + FIELDS = { + 1: ('address', p.UnicodeType, 0), + } + MESSAGE_WIRE_TYPE = 115 diff --git a/trezorlib/messages/LiskDelegateType.py b/trezorlib/messages/LiskDelegateType.py new file mode 100644 index 0000000000..4afce0a22a --- /dev/null +++ b/trezorlib/messages/LiskDelegateType.py @@ -0,0 +1,8 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskDelegateType(p.MessageType): + FIELDS = { + 1: ('username', p.UnicodeType, 0), + } diff --git a/trezorlib/messages/LiskGetAddress.py b/trezorlib/messages/LiskGetAddress.py new file mode 100644 index 0000000000..e9d0b3fe5e --- /dev/null +++ b/trezorlib/messages/LiskGetAddress.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskGetAddress(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('show_display', p.BoolType, 0), + } + MESSAGE_WIRE_TYPE = 114 diff --git a/trezorlib/messages/LiskGetPublicKey.py b/trezorlib/messages/LiskGetPublicKey.py new file mode 100644 index 0000000000..bb6e30f919 --- /dev/null +++ b/trezorlib/messages/LiskGetPublicKey.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskGetPublicKey(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('show_display', p.BoolType, 0), + } + MESSAGE_WIRE_TYPE = 121 diff --git a/trezorlib/messages/LiskMessageSignature.py b/trezorlib/messages/LiskMessageSignature.py new file mode 100644 index 0000000000..46e7fc6102 --- /dev/null +++ b/trezorlib/messages/LiskMessageSignature.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskMessageSignature(p.MessageType): + FIELDS = { + 1: ('address', p.UnicodeType, 0), + 2: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 119 diff --git a/trezorlib/messages/LiskMultisignatureType.py b/trezorlib/messages/LiskMultisignatureType.py new file mode 100644 index 0000000000..223cd96ce9 --- /dev/null +++ b/trezorlib/messages/LiskMultisignatureType.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskMultisignatureType(p.MessageType): + FIELDS = { + 1: ('min', p.UVarintType, 0), + 2: ('life_time', p.UVarintType, 0), + 3: ('keys_group', p.UnicodeType, p.FLAG_REPEATED), + } diff --git a/trezorlib/messages/LiskPublicKey.py b/trezorlib/messages/LiskPublicKey.py new file mode 100644 index 0000000000..87cea3149d --- /dev/null +++ b/trezorlib/messages/LiskPublicKey.py @@ -0,0 +1,9 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskPublicKey(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 122 diff --git a/trezorlib/messages/LiskSignMessage.py b/trezorlib/messages/LiskSignMessage.py new file mode 100644 index 0000000000..9049e0ac87 --- /dev/null +++ b/trezorlib/messages/LiskSignMessage.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskSignMessage(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('message', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 118 diff --git a/trezorlib/messages/LiskSignTx.py b/trezorlib/messages/LiskSignTx.py new file mode 100644 index 0000000000..972268a022 --- /dev/null +++ b/trezorlib/messages/LiskSignTx.py @@ -0,0 +1,11 @@ +# Automatically generated by pb2py +from .. import protobuf as p +from .LiskTransactionCommon import LiskTransactionCommon + + +class LiskSignTx(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('transaction', LiskTransactionCommon, 0), + } + MESSAGE_WIRE_TYPE = 116 diff --git a/trezorlib/messages/LiskSignatureType.py b/trezorlib/messages/LiskSignatureType.py new file mode 100644 index 0000000000..b2c8322d8e --- /dev/null +++ b/trezorlib/messages/LiskSignatureType.py @@ -0,0 +1,8 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskSignatureType(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + } diff --git a/trezorlib/messages/LiskSignedTx.py b/trezorlib/messages/LiskSignedTx.py new file mode 100644 index 0000000000..271349ad56 --- /dev/null +++ b/trezorlib/messages/LiskSignedTx.py @@ -0,0 +1,9 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskSignedTx(p.MessageType): + FIELDS = { + 1: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 117 diff --git a/trezorlib/messages/LiskTransactionAsset.py b/trezorlib/messages/LiskTransactionAsset.py new file mode 100644 index 0000000000..1b924a78e0 --- /dev/null +++ b/trezorlib/messages/LiskTransactionAsset.py @@ -0,0 +1,15 @@ +# Automatically generated by pb2py +from .. import protobuf as p +from .LiskDelegateType import LiskDelegateType +from .LiskMultisignatureType import LiskMultisignatureType +from .LiskSignatureType import LiskSignatureType + + +class LiskTransactionAsset(p.MessageType): + FIELDS = { + 1: ('signature', LiskSignatureType, 0), + 2: ('delegate', LiskDelegateType, 0), + 3: ('votes', p.UnicodeType, p.FLAG_REPEATED), + 4: ('multisignature', LiskMultisignatureType, 0), + 5: ('data', p.UnicodeType, 0), + } diff --git a/trezorlib/messages/LiskTransactionCommon.py b/trezorlib/messages/LiskTransactionCommon.py new file mode 100644 index 0000000000..159a50a535 --- /dev/null +++ b/trezorlib/messages/LiskTransactionCommon.py @@ -0,0 +1,17 @@ +# Automatically generated by pb2py +from .. import protobuf as p +from .LiskTransactionAsset import LiskTransactionAsset + + +class LiskTransactionCommon(p.MessageType): + FIELDS = { + 1: ('type', p.UVarintType, 0), + 2: ('amount', p.UVarintType, 0), # default=0 + 3: ('fee', p.UVarintType, 0), + 4: ('recipient_id', p.UnicodeType, 0), + 5: ('sender_public_key', p.BytesType, 0), + 6: ('requester_public_key', p.BytesType, 0), + 7: ('signature', p.BytesType, 0), + 8: ('timestamp', p.UVarintType, 0), + 9: ('asset', LiskTransactionAsset, 0), + } diff --git a/trezorlib/messages/LiskTransactionType.py b/trezorlib/messages/LiskTransactionType.py new file mode 100644 index 0000000000..b4e55b08db --- /dev/null +++ b/trezorlib/messages/LiskTransactionType.py @@ -0,0 +1,9 @@ +# Automatically generated by pb2py +Transfer = 0 +RegisterSecondPassphrase = 1 +RegisterDelegate = 2 +CastVotes = 3 +RegisterMultisignatureAccount = 4 +CreateDapp = 5 +TransferIntoDapp = 6 +TransferOutOfDapp = 7 diff --git a/trezorlib/messages/LiskVerifyMessage.py b/trezorlib/messages/LiskVerifyMessage.py new file mode 100644 index 0000000000..bbd1446035 --- /dev/null +++ b/trezorlib/messages/LiskVerifyMessage.py @@ -0,0 +1,11 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class LiskVerifyMessage(p.MessageType): + FIELDS = { + 1: ('signature', p.BytesType, 0), + 2: ('public_key', p.BytesType, 0), + 3: ('message', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 120 diff --git a/trezorlib/messages/MessageType.py b/trezorlib/messages/MessageType.py index 8409048cdc..2c76d2115d 100644 --- a/trezorlib/messages/MessageType.py +++ b/trezorlib/messages/MessageType.py @@ -84,3 +84,31 @@ DebugLinkMemoryRead = 110 DebugLinkMemory = 111 DebugLinkMemoryWrite = 112 DebugLinkFlashErase = 113 +LiskGetAddress = 114 +LiskAddress = 115 +LiskSignTx = 116 +LiskSignedTx = 117 +LiskSignMessage = 118 +LiskMessageSignature = 119 +LiskVerifyMessage = 120 +LiskGetPublicKey = 121 +LiskPublicKey = 122 +StellarGetPublicKey = 200 +StellarPublicKey = 201 +StellarSignTx = 202 +StellarTxOpRequest = 203 +StellarSignMessage = 204 +StellarMessageSignature = 205 +StellarVerifyMessage = 206 +StellarCreateAccountOp = 210 +StellarPaymentOp = 211 +StellarPathPaymentOp = 212 +StellarManageOfferOp = 213 +StellarCreatePassiveOfferOp = 214 +StellarSetOptionsOp = 215 +StellarChangeTrustOp = 216 +StellarAllowTrustOp = 217 +StellarAccountMergeOp = 218 +StellarManageDataOp = 220 +StellarBumpSequenceOp = 221 +StellarSignedTx = 230 diff --git a/trezorlib/messages/StellarAccountMergeOp.py b/trezorlib/messages/StellarAccountMergeOp.py new file mode 100644 index 0000000000..83732ae9b9 --- /dev/null +++ b/trezorlib/messages/StellarAccountMergeOp.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarAccountMergeOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('destination_account', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 218 diff --git a/trezorlib/messages/StellarAllowTrustOp.py b/trezorlib/messages/StellarAllowTrustOp.py new file mode 100644 index 0000000000..2232c3ec1c --- /dev/null +++ b/trezorlib/messages/StellarAllowTrustOp.py @@ -0,0 +1,13 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarAllowTrustOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('trusted_account', p.BytesType, 0), + 3: ('asset_type', p.UVarintType, 0), + 4: ('asset_code', p.UnicodeType, 0), + 5: ('is_authorized', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 217 diff --git a/trezorlib/messages/StellarAssetType.py b/trezorlib/messages/StellarAssetType.py new file mode 100644 index 0000000000..c997a7d674 --- /dev/null +++ b/trezorlib/messages/StellarAssetType.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarAssetType(p.MessageType): + FIELDS = { + 1: ('type', p.UVarintType, 0), + 2: ('code', p.UnicodeType, 0), + 3: ('issuer', p.BytesType, 0), + } diff --git a/trezorlib/messages/StellarBumpSequenceOp.py b/trezorlib/messages/StellarBumpSequenceOp.py new file mode 100644 index 0000000000..ba82bd6c14 --- /dev/null +++ b/trezorlib/messages/StellarBumpSequenceOp.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarBumpSequenceOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('bump_to', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 221 diff --git a/trezorlib/messages/StellarChangeTrustOp.py b/trezorlib/messages/StellarChangeTrustOp.py new file mode 100644 index 0000000000..86884830ec --- /dev/null +++ b/trezorlib/messages/StellarChangeTrustOp.py @@ -0,0 +1,12 @@ +# Automatically generated by pb2py +from .. import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarChangeTrustOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('asset', StellarAssetType, 0), + 3: ('limit', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 216 diff --git a/trezorlib/messages/StellarCreateAccountOp.py b/trezorlib/messages/StellarCreateAccountOp.py new file mode 100644 index 0000000000..e1fee62db6 --- /dev/null +++ b/trezorlib/messages/StellarCreateAccountOp.py @@ -0,0 +1,11 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarCreateAccountOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('new_account', p.BytesType, 0), + 3: ('starting_balance', p.Sint64Type, 0), + } + MESSAGE_WIRE_TYPE = 210 diff --git a/trezorlib/messages/StellarCreatePassiveOfferOp.py b/trezorlib/messages/StellarCreatePassiveOfferOp.py new file mode 100644 index 0000000000..b84ab0662f --- /dev/null +++ b/trezorlib/messages/StellarCreatePassiveOfferOp.py @@ -0,0 +1,15 @@ +# Automatically generated by pb2py +from .. import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarCreatePassiveOfferOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('selling_asset', StellarAssetType, 0), + 3: ('buying_asset', StellarAssetType, 0), + 4: ('amount', p.Sint64Type, 0), + 5: ('price_n', p.UVarintType, 0), + 6: ('price_d', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 214 diff --git a/trezorlib/messages/StellarGetPublicKey.py b/trezorlib/messages/StellarGetPublicKey.py new file mode 100644 index 0000000000..2d2272aae2 --- /dev/null +++ b/trezorlib/messages/StellarGetPublicKey.py @@ -0,0 +1,9 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarGetPublicKey(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + } + MESSAGE_WIRE_TYPE = 200 diff --git a/trezorlib/messages/StellarManageDataOp.py b/trezorlib/messages/StellarManageDataOp.py new file mode 100644 index 0000000000..140019354b --- /dev/null +++ b/trezorlib/messages/StellarManageDataOp.py @@ -0,0 +1,11 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarManageDataOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('key', p.UnicodeType, 0), + 3: ('value', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 220 diff --git a/trezorlib/messages/StellarManageOfferOp.py b/trezorlib/messages/StellarManageOfferOp.py new file mode 100644 index 0000000000..8a77ad4417 --- /dev/null +++ b/trezorlib/messages/StellarManageOfferOp.py @@ -0,0 +1,16 @@ +# Automatically generated by pb2py +from .. import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarManageOfferOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('selling_asset', StellarAssetType, 0), + 3: ('buying_asset', StellarAssetType, 0), + 4: ('amount', p.Sint64Type, 0), + 5: ('price_n', p.UVarintType, 0), + 6: ('price_d', p.UVarintType, 0), + 7: ('offer_id', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 213 diff --git a/trezorlib/messages/StellarMessageSignature.py b/trezorlib/messages/StellarMessageSignature.py new file mode 100644 index 0000000000..430ea9449c --- /dev/null +++ b/trezorlib/messages/StellarMessageSignature.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarMessageSignature(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + 2: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 205 diff --git a/trezorlib/messages/StellarPathPaymentOp.py b/trezorlib/messages/StellarPathPaymentOp.py new file mode 100644 index 0000000000..906bf3499a --- /dev/null +++ b/trezorlib/messages/StellarPathPaymentOp.py @@ -0,0 +1,16 @@ +# Automatically generated by pb2py +from .. import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarPathPaymentOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('send_asset', StellarAssetType, 0), + 3: ('send_max', p.Sint64Type, 0), + 4: ('destination_account', p.BytesType, 0), + 5: ('destination_asset', StellarAssetType, 0), + 6: ('destination_amount', p.Sint64Type, 0), + 7: ('paths', StellarAssetType, p.FLAG_REPEATED), + } + MESSAGE_WIRE_TYPE = 212 diff --git a/trezorlib/messages/StellarPaymentOp.py b/trezorlib/messages/StellarPaymentOp.py new file mode 100644 index 0000000000..ca15f51a90 --- /dev/null +++ b/trezorlib/messages/StellarPaymentOp.py @@ -0,0 +1,13 @@ +# Automatically generated by pb2py +from .. import protobuf as p +from .StellarAssetType import StellarAssetType + + +class StellarPaymentOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('destination_account', p.BytesType, 0), + 3: ('asset', StellarAssetType, 0), + 4: ('amount', p.Sint64Type, 0), + } + MESSAGE_WIRE_TYPE = 211 diff --git a/trezorlib/messages/StellarPublicKey.py b/trezorlib/messages/StellarPublicKey.py new file mode 100644 index 0000000000..1229d25f4f --- /dev/null +++ b/trezorlib/messages/StellarPublicKey.py @@ -0,0 +1,9 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarPublicKey(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 201 diff --git a/trezorlib/messages/StellarSetOptionsOp.py b/trezorlib/messages/StellarSetOptionsOp.py new file mode 100644 index 0000000000..53d3c2ff88 --- /dev/null +++ b/trezorlib/messages/StellarSetOptionsOp.py @@ -0,0 +1,20 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarSetOptionsOp(p.MessageType): + FIELDS = { + 1: ('source_account', p.BytesType, 0), + 2: ('inflation_destination_account', p.BytesType, 0), + 3: ('clear_flags', p.UVarintType, 0), + 4: ('set_flags', p.UVarintType, 0), + 5: ('master_weight', p.UVarintType, 0), + 6: ('low_threshold', p.UVarintType, 0), + 7: ('medium_threshold', p.UVarintType, 0), + 8: ('high_threshold', p.UVarintType, 0), + 9: ('home_domain', p.UnicodeType, 0), + 10: ('signer_type', p.UVarintType, 0), + 11: ('signer_key', p.BytesType, 0), + 12: ('signer_weight', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 215 diff --git a/trezorlib/messages/StellarSignMessage.py b/trezorlib/messages/StellarSignMessage.py new file mode 100644 index 0000000000..5d51be39de --- /dev/null +++ b/trezorlib/messages/StellarSignMessage.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarSignMessage(p.MessageType): + FIELDS = { + 1: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 2: ('message', p.UnicodeType, 0), + } + MESSAGE_WIRE_TYPE = 204 diff --git a/trezorlib/messages/StellarSignTx.py b/trezorlib/messages/StellarSignTx.py new file mode 100644 index 0000000000..a78649d45b --- /dev/null +++ b/trezorlib/messages/StellarSignTx.py @@ -0,0 +1,21 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarSignTx(p.MessageType): + FIELDS = { + 1: ('protocol_version', p.UVarintType, 0), + 2: ('address_n', p.UVarintType, p.FLAG_REPEATED), + 3: ('network_passphrase', p.UnicodeType, 0), + 4: ('source_account', p.BytesType, 0), + 5: ('fee', p.UVarintType, 0), + 6: ('sequence_number', p.UVarintType, 0), + 8: ('timebounds_start', p.UVarintType, 0), + 9: ('timebounds_end', p.UVarintType, 0), + 10: ('memo_type', p.UVarintType, 0), + 11: ('memo_text', p.UnicodeType, 0), + 12: ('memo_id', p.UVarintType, 0), + 13: ('memo_hash', p.BytesType, 0), + 14: ('num_operations', p.UVarintType, 0), + } + MESSAGE_WIRE_TYPE = 202 diff --git a/trezorlib/messages/StellarSignedTx.py b/trezorlib/messages/StellarSignedTx.py new file mode 100644 index 0000000000..9ae7a314c0 --- /dev/null +++ b/trezorlib/messages/StellarSignedTx.py @@ -0,0 +1,10 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarSignedTx(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + 2: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 230 diff --git a/trezorlib/messages/StellarTxOpRequest.py b/trezorlib/messages/StellarTxOpRequest.py new file mode 100644 index 0000000000..8b93fba824 --- /dev/null +++ b/trezorlib/messages/StellarTxOpRequest.py @@ -0,0 +1,6 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarTxOpRequest(p.MessageType): + MESSAGE_WIRE_TYPE = 203 diff --git a/trezorlib/messages/StellarVerifyMessage.py b/trezorlib/messages/StellarVerifyMessage.py new file mode 100644 index 0000000000..967bdea48b --- /dev/null +++ b/trezorlib/messages/StellarVerifyMessage.py @@ -0,0 +1,11 @@ +# Automatically generated by pb2py +from .. import protobuf as p + + +class StellarVerifyMessage(p.MessageType): + FIELDS = { + 1: ('public_key', p.BytesType, 0), + 2: ('message', p.BytesType, 0), + 3: ('signature', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 206 diff --git a/trezorlib/messages/__init__.py b/trezorlib/messages/__init__.py index 54b9b5174f..663224076f 100644 --- a/trezorlib/messages/__init__.py +++ b/trezorlib/messages/__init__.py @@ -4,6 +4,11 @@ from .CoinType import CoinType from .HDNodePathType import HDNodePathType from .HDNodeType import HDNodeType from .IdentityType import IdentityType +from .LiskDelegateType import LiskDelegateType +from .LiskMultisignatureType import LiskMultisignatureType +from .LiskSignatureType import LiskSignatureType +from .LiskTransactionAsset import LiskTransactionAsset +from .LiskTransactionCommon import LiskTransactionCommon from .MultisigRedeemScriptType import MultisigRedeemScriptType from .NEMAggregateModification import NEMAggregateModification from .NEMCosignatoryModification import NEMCosignatoryModification @@ -15,6 +20,7 @@ from .NEMMosaicSupplyChange import NEMMosaicSupplyChange from .NEMProvisionNamespace import NEMProvisionNamespace from .NEMTransactionCommon import NEMTransactionCommon from .NEMTransfer import NEMTransfer +from .StellarAssetType import StellarAssetType from .TransactionType import TransactionType from .TxInputType import TxInputType from .TxOutputBinType import TxOutputBinType @@ -34,6 +40,7 @@ from . import NEMMosaicLevy from . import NEMSupplyChangeType from . import NEMModificationType from . import NEMImportanceTransferMode +from . import LiskTransactionType from .Address import Address from .ApplyFlags import ApplyFlags from .ApplySettings import ApplySettings @@ -86,6 +93,15 @@ from .GetEntropy import GetEntropy from .GetFeatures import GetFeatures from .GetPublicKey import GetPublicKey from .Initialize import Initialize +from .LiskAddress import LiskAddress +from .LiskGetAddress import LiskGetAddress +from .LiskGetPublicKey import LiskGetPublicKey +from .LiskMessageSignature import LiskMessageSignature +from .LiskPublicKey import LiskPublicKey +from .LiskSignMessage import LiskSignMessage +from .LiskSignTx import LiskSignTx +from .LiskSignedTx import LiskSignedTx +from .LiskVerifyMessage import LiskVerifyMessage from .LoadDevice import LoadDevice from .MessageSignature import MessageSignature from .NEMAddress import NEMAddress @@ -111,6 +127,25 @@ from .SignMessage import SignMessage from .SignTx import SignTx from .SignedIdentity import SignedIdentity from .SimpleSignTx import SimpleSignTx +from .StellarAccountMergeOp import StellarAccountMergeOp +from .StellarAllowTrustOp import StellarAllowTrustOp +from .StellarBumpSequenceOp import StellarBumpSequenceOp +from .StellarChangeTrustOp import StellarChangeTrustOp +from .StellarCreateAccountOp import StellarCreateAccountOp +from .StellarCreatePassiveOfferOp import StellarCreatePassiveOfferOp +from .StellarGetPublicKey import StellarGetPublicKey +from .StellarManageDataOp import StellarManageDataOp +from .StellarManageOfferOp import StellarManageOfferOp +from .StellarMessageSignature import StellarMessageSignature +from .StellarPathPaymentOp import StellarPathPaymentOp +from .StellarPaymentOp import StellarPaymentOp +from .StellarPublicKey import StellarPublicKey +from .StellarSetOptionsOp import StellarSetOptionsOp +from .StellarSignMessage import StellarSignMessage +from .StellarSignTx import StellarSignTx +from .StellarSignedTx import StellarSignedTx +from .StellarTxOpRequest import StellarTxOpRequest +from .StellarVerifyMessage import StellarVerifyMessage from .Success import Success from .TxAck import TxAck from .TxRequest import TxRequest diff --git a/vendor/trezor-common b/vendor/trezor-common index 233456f077..9abe3a7c69 160000 --- a/vendor/trezor-common +++ b/vendor/trezor-common @@ -1 +1 @@ -Subproject commit 233456f0774dd31cc10c445313dd429ba1140971 +Subproject commit 9abe3a7c69000cc7ee3cda2ec940193fa9d62e6c From 3e742177d23f39cf46ec2a7ecd5306589ce13d52 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 17:38:00 +0300 Subject: [PATCH 48/57] lisk: Add lisk_get_address method --- trezorctl | 15 ++++++++++ trezorlib/client.py | 10 +++++++ .../device_tests/test_msg_lisk_getaddress.py | 30 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 trezorlib/tests/device_tests/test_msg_lisk_getaddress.py diff --git a/trezorctl b/trezorctl index 923cfec745..250fbe13de 100755 --- a/trezorctl +++ b/trezorctl @@ -861,6 +861,21 @@ def nem_sign_tx(connect, address, file, broadcast): return payload +# +# Lisk functions +# + + +@cli.command(help='Get Lisk address for specified path.') +@click.option('-n', '--address', required=True, help="BIP-32 path, e.g. m/44'/134'/0'/0'") +@click.option('-d', '--show-display', is_flag=True) +@click.pass_obj +def lisk_get_address(connect, address, show_display): + client = connect() + address_n = client.expand_path(address) + return client.lisk_get_address(address_n, show_display) + + # # CoSi functions # diff --git a/trezorlib/client.py b/trezorlib/client.py index c885d477df..da7d7f07b1 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -627,6 +627,16 @@ class ProtocolMixin(object): return True return False + # + # Lisk functions + # + + @field('address') + @expect(proto.LiskAddress) + def lisk_get_address(self, n, show_display=False): + n = self._convert_prime(n) + return self.call(proto.LiskGetAddress(address_n=n, show_display=show_display)) + @field('entropy') @expect(proto.Entropy) def get_entropy(self, size): diff --git a/trezorlib/tests/device_tests/test_msg_lisk_getaddress.py b/trezorlib/tests/device_tests/test_msg_lisk_getaddress.py new file mode 100644 index 0000000000..49d9e12938 --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_lisk_getaddress.py @@ -0,0 +1,30 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2012-2016 Marek Palatinus +# Copyright (C) 2012-2016 Pavol Rusnak +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * + + +@pytest.mark.skip_t1 +class TestMsgLiskGetaddress(TrezorTest): + + def test_lisk_getaddress(self): + self.setup_mnemonic_nopin_nopassphrase() + assert self.client.lisk_get_address([2147483692, 2147483782]) == '1431530009238518937L' + assert self.client.lisk_get_address([2147483692, 2147483782, 2147483648]) == '17563781916205589679L' + assert self.client.lisk_get_address([2147483692, 2147483782, 2147483648, 2147483649]) == '1874186517773691964L' + assert self.client.lisk_get_address([2147483692, 2147483782, 2147484647, 2147484647]) == '16295203558710684671L' From d3685639f99d336104ac1adb7a93078b1804b37b Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 17:45:58 +0300 Subject: [PATCH 49/57] lisk: Add lisk_sign_message --- trezorctl | 16 +++++++++ trezorlib/client.py | 6 ++++ .../device_tests/test_msg_lisk_signmessage.py | 35 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 trezorlib/tests/device_tests/test_msg_lisk_signmessage.py diff --git a/trezorctl b/trezorctl index 250fbe13de..00e8067887 100755 --- a/trezorctl +++ b/trezorctl @@ -876,6 +876,22 @@ def lisk_get_address(connect, address, show_display): return client.lisk_get_address(address_n, show_display) +@cli.command(help='Sign message with Lisk address.') +@click.option('-n', '--address', required=True, help="BIP-32 path, e.g. m/44'/134'/0'/0'") +@click.argument('message') +@click.pass_obj +def lisk_sign_message(connect, address, message): + client = connect() + address_n = client.expand_path(address) + res = client.lisk_sign_message(address_n, message) + output = { + 'message': message, + 'address': res.address, + 'signature': binascii.hexlify(res.signature).decode() + } + return output + + # # CoSi functions # diff --git a/trezorlib/client.py b/trezorlib/client.py index da7d7f07b1..b095ab7f00 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -637,6 +637,12 @@ class ProtocolMixin(object): n = self._convert_prime(n) return self.call(proto.LiskGetAddress(address_n=n, show_display=show_display)) + @expect(proto.LiskMessageSignature) + def lisk_sign_message(self, n, message): + n = self._convert_prime(n) + message = normalize_nfc(message) + return self.call(proto.LiskSignMessage(address_n=n, message=message)) + @field('entropy') @expect(proto.Entropy) def get_entropy(self, size): diff --git a/trezorlib/tests/device_tests/test_msg_lisk_signmessage.py b/trezorlib/tests/device_tests/test_msg_lisk_signmessage.py new file mode 100644 index 0000000000..72db0c9c50 --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_lisk_signmessage.py @@ -0,0 +1,35 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2016-2017 Pavol Rusnak +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * + + +@pytest.mark.skip_t1 +class TestMsgLiskSignmessage(TrezorTest): + + def test_sign(self): + self.setup_mnemonic_nopin_nopassphrase() + sig = self.client.lisk_sign_message([2147483692, 2147483782, 2147483648, 2147483648], 'This is an example of a signed message.') + assert sig.address == '7623396847864198749L' + assert hexlify(sig.signature) == b'af1d384cce25354b5af129662caed6f3514c6f1f6a206662d301fd56aa5549aa23c3f82009f213a7a4d9297015c2e5b06584273df7c42d78b4e531fe4d4fc80e' + + def test_sign_long(self): + self.setup_mnemonic_nopin_nopassphrase() + sig = self.client.lisk_sign_message([2147483692, 2147483782, 2147483648], 'VeryLongMessage!' * 64) + assert sig.address == '17563781916205589679L' + print(hexlify(sig.signature)) + assert hexlify(sig.signature) == b'a675152c2af34e85dbd75740681efb7d67bf910561d6c9d1e075be2f99d9bc544d62c52f6619756b0e329a2f2d82756ced53b4261a028fcee0d37d7e641ef404' From 514e808b567b8b595505a8860576ca156bf81ab6 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 18:23:09 +0300 Subject: [PATCH 50/57] lisk: Add lisk_verify_message --- trezorctl | 11 ++++ trezorlib/client.py | 8 +++ .../test_msg_lisk_verifymessage.py | 51 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py diff --git a/trezorctl b/trezorctl index 00e8067887..b901668f87 100755 --- a/trezorctl +++ b/trezorctl @@ -892,6 +892,17 @@ def lisk_sign_message(connect, address, message): return output +@cli.command(help='Verify message signed with Lisk address.') +@click.argument('pubkey') +@click.argument('signature') +@click.argument('message') +@click.pass_obj +def lisk_verify_message(connect, pubkey, signature, message): + signature = bytes.fromhex(signature) + pubkey = bytes.fromhex(pubkey) + return connect().lisk_verify_message(pubkey, signature, message) + + # # CoSi functions # diff --git a/trezorlib/client.py b/trezorlib/client.py index b095ab7f00..023c725817 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -643,6 +643,14 @@ class ProtocolMixin(object): message = normalize_nfc(message) return self.call(proto.LiskSignMessage(address_n=n, message=message)) + def lisk_verify_message(self, pubkey, signature, message): + message = normalize_nfc(message) + try: + resp = self.call(proto.LiskVerifyMessage(signature=signature, public_key=pubkey, message=message)) + except CallException as e: + resp = e + return isinstance(resp, proto.Success) + @field('entropy') @expect(proto.Entropy) def get_entropy(self, size): diff --git a/trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py b/trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py new file mode 100644 index 0000000000..ee08f83474 --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py @@ -0,0 +1,51 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2016-2017 Pavol Rusnak +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * +from trezorlib import messages as proto + + +@pytest.mark.skip_t1 +class TestMsgLiskVerifymessage(TrezorTest): + + def test_verify(self): + self.setup_mnemonic_nopin_nopassphrase() + with self.client: + self.client.set_expected_responses([ + proto.ButtonRequest(code=proto.ButtonRequestType.Other), + proto.ButtonRequest(code=proto.ButtonRequestType.Other), + proto.Success(message='Message verified') + ]) + self.client.lisk_verify_message( + unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'), + unhexlify('af1d384cce25354b5af129662caed6f3514c6f1f6a206662d301fd56aa5549aa23c3f82009f213a7a4d9297015c2e5b06584273df7c42d78b4e531fe4d4fc80e'), + 'This is an example of a signed message.' + ) + + def test_verify_long(self): + self.setup_mnemonic_nopin_nopassphrase() + with self.client: + self.client.set_expected_responses([ + proto.ButtonRequest(code=proto.ButtonRequestType.Other), + proto.ButtonRequest(code=proto.ButtonRequestType.Other), + proto.Success(message='Message verified') + ]) + self.client.lisk_verify_message( + unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'), + unhexlify('7b4b481f6a07a874bdd1b590cd2b933c8b571c721484d9dc303f81b22d1f3c5f55ffe0704dbfd543ff9ea3e795facda871ddb422522257d33a8fe16ab4169601'), + 'VeryLongMessage!' * 64 + ) From 5e1168c48d3b24976307a2a9e6806f0fb57c2853 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 18:31:11 +0300 Subject: [PATCH 51/57] lisk: Add lisk_get_publickey --- trezorctl | 14 ++++++++++ trezorlib/client.py | 5 ++++ .../test_msg_lisk_getpublickey.py | 27 +++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py diff --git a/trezorctl b/trezorctl index b901668f87..b9531cd9fc 100755 --- a/trezorctl +++ b/trezorctl @@ -876,6 +876,20 @@ def lisk_get_address(connect, address, show_display): return client.lisk_get_address(address_n, show_display) +@cli.command(help='Get Lisk public key for specified path.') +@click.option('-n', '--address', required=True, help="BIP-32 path, e.g. m/44'/134'/0'/0'") +@click.option('-d', '--show-display', is_flag=True) +@click.pass_obj +def lisk_get_public_key(connect, address, show_display): + client = connect() + address_n = client.expand_path(address) + res = client.lisk_get_public_key(address_n, show_display) + output = { + "public_key": binascii.hexlify(res.public_key).decode() + } + return output + + @cli.command(help='Sign message with Lisk address.') @click.option('-n', '--address', required=True, help="BIP-32 path, e.g. m/44'/134'/0'/0'") @click.argument('message') diff --git a/trezorlib/client.py b/trezorlib/client.py index 023c725817..af1daf3435 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -637,6 +637,11 @@ class ProtocolMixin(object): n = self._convert_prime(n) return self.call(proto.LiskGetAddress(address_n=n, show_display=show_display)) + @expect(proto.LiskPublicKey) + def lisk_get_public_key(self, n, show_display=False): + n = self._convert_prime(n) + return self.call(proto.LiskGetPublicKey(address_n=n, show_display=show_display)) + @expect(proto.LiskMessageSignature) def lisk_sign_message(self, n, message): n = self._convert_prime(n) diff --git a/trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py b/trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py new file mode 100644 index 0000000000..60cb64f3b3 --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py @@ -0,0 +1,27 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2016-2017 Pavol Rusnak +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * + + +@pytest.mark.skip_t1 +class TestMsgLiskGetPublicKey(TrezorTest): + + def test_lisk_get_public_key(self): + self.setup_mnemonic_nopin_nopassphrase() + sig = self.client.lisk_get_public_key([2147483692, 2147483782, 2147483648, 2147483648]) + assert hexlify(sig.public_key) == b'eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294' From 45cca15e5f4e7768d59362ebd0f7525731bd2602 Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Mon, 16 Apr 2018 20:56:07 +0300 Subject: [PATCH 52/57] lisk: Add lisk_sign_tx --- trezorctl | 17 ++ trezorlib/client.py | 45 ++++- .../device_tests/test_msg_lisk_signtx.py | 172 ++++++++++++++++++ 3 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 trezorlib/tests/device_tests/test_msg_lisk_signtx.py diff --git a/trezorctl b/trezorctl index b9531cd9fc..27cb42b7b8 100755 --- a/trezorctl +++ b/trezorctl @@ -917,6 +917,23 @@ def lisk_verify_message(connect, pubkey, signature, message): return connect().lisk_verify_message(pubkey, signature, message) +@cli.command(help='Sign Lisk transaction.') +@click.option('-n', '--address', required=True, help="BIP-32 path to signing key, e.g. m/44'/134'/0'/0'") +@click.option('-f', '--file', type=click.File('r'), default='-', help='Transaction in JSON format') +# @click.option('-b', '--broadcast', help='Broadcast Lisk transaction') +@click.pass_obj +def lisk_sign_tx(connect, address, file): + client = connect() + address_n = client.expand_path(address) + transaction = client.lisk_sign_tx(address_n, json.load(file)) + + payload = { + "signature": binascii.hexlify(transaction.signature).decode() + } + + return payload + + # # CoSi functions # diff --git a/trezorlib/client.py b/trezorlib/client.py index af1daf3435..5b5de149f6 100644 --- a/trezorlib/client.py +++ b/trezorlib/client.py @@ -654,7 +654,50 @@ class ProtocolMixin(object): resp = self.call(proto.LiskVerifyMessage(signature=signature, public_key=pubkey, message=message)) except CallException as e: resp = e - return isinstance(resp, proto.Success) + return isinstance(resp, proto.Success) + + @expect(proto.LiskSignedTx) + def lisk_sign_tx(self, n, transaction): + n = self._convert_prime(n) + + def asset_to_proto(asset): + msg = proto.LiskTransactionAsset() + + if "votes" in asset: + msg.votes = asset["votes"] + if "data" in asset: + msg.data = asset["data"] + if "signature" in asset: + msg.signature = proto.LiskSignatureType() + msg.signature.public_key = binascii.unhexlify(asset["signature"]["publicKey"]) + if "delegate" in asset: + msg.delegate = proto.LiskDelegateType() + msg.delegate.username = asset["delegate"]["username"] + if "multisignature" in asset: + msg.multisignature = proto.LiskMultisignatureType() + msg.multisignature.min = asset["multisignature"]["min"] + msg.multisignature.life_time = asset["multisignature"]["lifetime"] + msg.multisignature.keys_group = asset["multisignature"]["keysgroup"] + return msg + + msg = proto.LiskTransactionCommon() + + msg.type = transaction["type"] + msg.fee = int(transaction["fee"]) # Lisk use strings for big numbers (javascript issue) + msg.amount = int(transaction["amount"]) # And we convert it back to number + msg.timestamp = transaction["timestamp"] + + if "recipientId" in transaction: + msg.recipient_id = transaction["recipientId"] + if "senderPublicKey" in transaction: + msg.sender_public_key = binascii.unhexlify(transaction["senderPublicKey"]) + if "requesterPublicKey" in transaction: + msg.requester_public_key = binascii.unhexlify(transaction["requesterPublicKey"]) + if "signature" in transaction: + msg.signature = binascii.unhexlify(transaction["signature"]) + + msg.asset = asset_to_proto(transaction["asset"]) + return self.call(proto.LiskSignTx(address_n=n, transaction=msg)) @field('entropy') @expect(proto.Entropy) diff --git a/trezorlib/tests/device_tests/test_msg_lisk_signtx.py b/trezorlib/tests/device_tests/test_msg_lisk_signtx.py new file mode 100644 index 0000000000..65518c74fa --- /dev/null +++ b/trezorlib/tests/device_tests/test_msg_lisk_signtx.py @@ -0,0 +1,172 @@ +# This file is part of the TREZOR project. +# +# Copyright (C) 2012-2016 Marek Palatinus +# Copyright (C) 2012-2016 Pavol Rusnak +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +from .common import * +from trezorlib import messages as proto + +PUBLIC_KEY = unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294') + + +@pytest.mark.skip_t1 +class TestMsgLiskSignTx(TrezorTest): + + def test_lisk_sign_tx_send(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + proto.LiskSignedTx( + signature=unhexlify('b62717d581e5713bca60b758b661e6cfa091addc6caedd57534e06cda805943ee80797b9fb9a1e1b2bd584e292d2a7f832a4d1b3f15f00e1ee1b72de7e195a08') + ) + ]) + + self.client.lisk_sign_tx(self.client.expand_path("m/44'/134'/0'/0'"), { + "amount": "10000000", + "recipientId": "9971262264659915921L", + "timestamp": 57525937, + "type": 0, + "fee": "10000000", + "asset": {} + }) + + def test_lisk_sign_tx_send_with_data(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + proto.LiskSignedTx( + signature=unhexlify('5dd0dbb87ee46f3e985b1ef2df85cb0bec481e8601d150388f73e198cdd57a698eab076c7cd5b281fbb6a83dd3dc64d91a6eccd1614dffd46f101194ffa3a004') + ) + ]) + + self.client.lisk_sign_tx(self.client.expand_path("m/44'/134'/0'/0'"), { + "amount": "10000000", + "recipientId": "9971262264659915921L", + "timestamp": 57525937, + "type": 0, + "fee": "20000000", + "asset": { + "data": "Test data" + } + }) + + def test_lisk_sign_tx_second_signature(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + proto.ButtonRequest(code=proto.ButtonRequestType.PublicKey), + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + proto.LiskSignedTx( + signature=unhexlify('a3165c77c53d0407c4b0037e9aa40155c531e779049a2a40ee374877f4f9e72e69ae2cfc387c5ee6dd7770069b24e5a9914fb7c289491e10dd67931dee14b304') + ) + ]) + + self.client.lisk_sign_tx(self.client.expand_path("m/44'/134'/0'/0'"), { + "amount": "0", + "timestamp": 57525937, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09" + } + } + }) + + def test_lisk_sign_tx_delegate_registration(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + proto.LiskSignedTx( + signature=unhexlify('fb7403f4c582ed9c4a65699442e9b61f01718c4455ca3bd68d3840d057ef62d6c361b0242f4988fd53d155892a84a84b675208c80a8cbde49e7b1e2cc762cc08') + ) + ]) + + self.client.lisk_sign_tx(self.client.expand_path("m/44'/134'/0'/0'"), { + "amount": "0", + "timestamp": 57525937, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "trezor_t" + } + } + }) + + def test_lisk_sign_tx_cast_votes(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + proto.LiskSignedTx( + signature=unhexlify('1d0599a8387edaa4a6d309b8a78accd1ceaff20ff9d87136b01cba0efbcb9781c13dc2b0bab5a1ea4f196d8dcc9dbdbd2d56dbffcc088fc77686b2e2c2fe560f') + ) + ]) + + self.client.lisk_sign_tx(self.client.expand_path("m/44'/134'/0'/0'"), { + "amount": "0", + "timestamp": 57525937, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b002f58531c074c7190714523eec08c48db8c7cfc0c943097db1a2e82ed87f84", + "-ec111c8ad482445cfe83d811a7edd1f1d2765079c99d7d958cca1354740b7614" + ] + } + }) + + def test_lisk_sign_tx_multisignature(self): + self.setup_mnemonic_nopin_nopassphrase() + + with self.client: + self.client.set_expected_responses([ + proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), + proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), + proto.LiskSignedTx( + signature=unhexlify('99d201637931cc546e240569d9d6d84add989d81d1b03b34b966625ad49e334986868368d5b1f04599c6330f6bd0223635e032014ecb405501a02842dd5c320f') + ) + ]) + + self.client.lisk_sign_tx(self.client.expand_path("m/44'/134'/0'/0'"), { + "amount": "0", + "timestamp": 57525937, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 5, + "keysgroup": [ + "+5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09", + "+922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa" + ] + } + } + }) From 1008c45100a17bf90a25a4cd797f8ac54445f1b6 Mon Sep 17 00:00:00 2001 From: matejcik Date: Wed, 18 Apr 2018 15:46:10 +0200 Subject: [PATCH 53/57] tests: xfail Lisk tests until trezor-core#90 is merged --- trezorlib/tests/device_tests/test_msg_lisk_getaddress.py | 5 ++++- trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py | 6 +++++- trezorlib/tests/device_tests/test_msg_lisk_signmessage.py | 6 +++++- trezorlib/tests/device_tests/test_msg_lisk_signtx.py | 6 +++++- trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py | 6 +++++- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_lisk_getaddress.py b/trezorlib/tests/device_tests/test_msg_lisk_getaddress.py index 49d9e12938..5ad308fe37 100644 --- a/trezorlib/tests/device_tests/test_msg_lisk_getaddress.py +++ b/trezorlib/tests/device_tests/test_msg_lisk_getaddress.py @@ -16,9 +16,12 @@ # You should have received a copy of the GNU Lesser General Public License # along with this library. If not, see . -from .common import * +import pytest + +from .common import TrezorTest +@pytest.mark.xfail # drop when trezor-core PR #90 is merged @pytest.mark.skip_t1 class TestMsgLiskGetaddress(TrezorTest): diff --git a/trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py b/trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py index 60cb64f3b3..1683be4efd 100644 --- a/trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py +++ b/trezorlib/tests/device_tests/test_msg_lisk_getpublickey.py @@ -15,9 +15,13 @@ # You should have received a copy of the GNU Lesser General Public License # along with this library. If not, see . -from .common import * +from binascii import hexlify +import pytest + +from .common import TrezorTest +@pytest.mark.xfail # drop when trezor-core PR #90 is merged @pytest.mark.skip_t1 class TestMsgLiskGetPublicKey(TrezorTest): diff --git a/trezorlib/tests/device_tests/test_msg_lisk_signmessage.py b/trezorlib/tests/device_tests/test_msg_lisk_signmessage.py index 72db0c9c50..022898eb9d 100644 --- a/trezorlib/tests/device_tests/test_msg_lisk_signmessage.py +++ b/trezorlib/tests/device_tests/test_msg_lisk_signmessage.py @@ -15,9 +15,13 @@ # You should have received a copy of the GNU Lesser General Public License # along with this library. If not, see . -from .common import * +from binascii import hexlify +import pytest + +from .common import TrezorTest +@pytest.mark.xfail # drop when trezor-core PR #90 is merged @pytest.mark.skip_t1 class TestMsgLiskSignmessage(TrezorTest): diff --git a/trezorlib/tests/device_tests/test_msg_lisk_signtx.py b/trezorlib/tests/device_tests/test_msg_lisk_signtx.py index 65518c74fa..81eb6c722e 100644 --- a/trezorlib/tests/device_tests/test_msg_lisk_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_lisk_signtx.py @@ -16,12 +16,16 @@ # You should have received a copy of the GNU Lesser General Public License # along with this library. If not, see . -from .common import * +from binascii import unhexlify +import pytest + +from .common import TrezorTest from trezorlib import messages as proto PUBLIC_KEY = unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294') +@pytest.mark.xfail # drop when trezor-core PR #90 is merged @pytest.mark.skip_t1 class TestMsgLiskSignTx(TrezorTest): diff --git a/trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py b/trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py index ee08f83474..46efbb7777 100644 --- a/trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py +++ b/trezorlib/tests/device_tests/test_msg_lisk_verifymessage.py @@ -15,10 +15,14 @@ # You should have received a copy of the GNU Lesser General Public License # along with this library. If not, see . -from .common import * +from binascii import unhexlify +import pytest + +from .common import TrezorTest from trezorlib import messages as proto +@pytest.mark.xfail # drop when trezor-core PR #90 is merged @pytest.mark.skip_t1 class TestMsgLiskVerifymessage(TrezorTest): From cc7e3eb9b50f66940beb80191bd37a956471fdcc Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 23 Apr 2018 13:01:29 +0200 Subject: [PATCH 54/57] travis: force setuptools>=38 which download prebuilt .whls this fixes a build error in dependencies that we seriously don't care about which was happening in travis's py34 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 71fbff6453..05602196c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ python: install: # Optimisation: build requirements as wheels, which get cached by Travis - pip install "pip>=7.0" wheel - - pip install "setuptools>=19.0" + - pip install "setuptools>=38" - pip install tox-travis - pip install flake8 # protobuf-related dependencies From 8f31422adf2b02afd6e2fc73eecfb54bed85ff8d Mon Sep 17 00:00:00 2001 From: Aleksey Popov Date: Sat, 21 Apr 2018 21:55:02 +0300 Subject: [PATCH 55/57] lisk: Fix wrong signature in tx tests --- trezorlib/tests/device_tests/test_msg_lisk_signtx.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_lisk_signtx.py b/trezorlib/tests/device_tests/test_msg_lisk_signtx.py index 81eb6c722e..a1d36385c1 100644 --- a/trezorlib/tests/device_tests/test_msg_lisk_signtx.py +++ b/trezorlib/tests/device_tests/test_msg_lisk_signtx.py @@ -81,7 +81,7 @@ class TestMsgLiskSignTx(TrezorTest): proto.ButtonRequest(code=proto.ButtonRequestType.PublicKey), proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), proto.LiskSignedTx( - signature=unhexlify('a3165c77c53d0407c4b0037e9aa40155c531e779049a2a40ee374877f4f9e72e69ae2cfc387c5ee6dd7770069b24e5a9914fb7c289491e10dd67931dee14b304') + signature=unhexlify('f02bdc40a7599c21d29db4080ff1ff8934f76eedf5b0c4fa695c8a64af2f0b40a5c4f92db203863eebbbfad8f0611a23f451ed8bb711490234cdfb034728fd01') ) ]) @@ -105,7 +105,7 @@ class TestMsgLiskSignTx(TrezorTest): proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), proto.LiskSignedTx( - signature=unhexlify('fb7403f4c582ed9c4a65699442e9b61f01718c4455ca3bd68d3840d057ef62d6c361b0242f4988fd53d155892a84a84b675208c80a8cbde49e7b1e2cc762cc08') + signature=unhexlify('5ac02b2882b9d7d0f944e48baadc27de1296cc08c3533f7c8e380fbbb9fb4a6ac81b5dc57060d7d8c68912eea24eb6e39024801bccc0d55020e2052b0c2bb701') ) ]) @@ -154,7 +154,7 @@ class TestMsgLiskSignTx(TrezorTest): proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput), proto.LiskSignedTx( - signature=unhexlify('99d201637931cc546e240569d9d6d84add989d81d1b03b34b966625ad49e334986868368d5b1f04599c6330f6bd0223635e032014ecb405501a02842dd5c320f') + signature=unhexlify('88923866c2d500a6927715699ab41a0f58ea4b52e552d90e923bc24ac9da240f2328c93f9ce043a1da4937d4b61c7f57c02fc931f9824d06b24731e7be23c506') ) ]) From 50e755be462455eb9b940aca3c4b487f9a843061 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Mon, 23 Apr 2018 16:54:21 +0100 Subject: [PATCH 56/57] tests/device/nem: known/unknown mosaics test --- .../test_msg_nem_signtx_transfers.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py index dfd079b2ec..1f52b8b972 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py @@ -129,6 +129,61 @@ class TestMsgNEMSignTx(TrezorTest): assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000010000001a0000000e000000030000006e656d0300000078656d40420f0000000000' assert tx.signature == signature + def test_nem_signtx_unknown_mosaic(self): + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 76809215, + "amount": 1000000, + "fee": 1000000, + "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "type": nem.TYPE_TRANSACTION_TRANSFER, + "deadline": 76895615, + "version": (0x98 << 24), + "message": { + }, + "mosaics": [ + { + "mosaicId": { + "namespaceId": "xxx", + "name": "aa", + }, + "quantity": 1000000, + }, + ], + }) + + assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f00000000000000000001000000190000000d0000000300000078787802000000616140420f0000000000' + assert hexlify(tx.signature) == b'4394067992b44692fbba761ea7cc6646959df1122efef46e23ebaa0c061bf7a5221ca014a2a32889dc9f7fc56a2440595f11944900809452e81166a6e6784e01' + + def test_nem_signtx_known_mosaic(self): + + self.setup_mnemonic_nopin_nopassphrase() + + tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { + "timeStamp": 76809215, + "amount": 9876543, + "fee": 1000000, + "recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT", + "type": nem.TYPE_TRANSACTION_TRANSFER, + "deadline": 76895615, + "version": (0x68 << 24), + "message": { + }, + "mosaics": [ + { + "mosaicId": { + "namespaceId": "dim", + "name": "token", + }, + "quantity": 1230009, + }, + ], + }) + + assert hexlify(tx.data) == b'0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c543fb496000000000000000000010000001c000000100000000300000064696d05000000746f6b656eb9c4120000000000' + assert hexlify(tx.signature) == b'b8dea33a8d654f190fe4d8455537869da6a707b710a38b00882bf3e5d8b5001285c34a2e5eca9cfe80c6908c38a5f9e6b2be15d327bdc6215e7350c541e1600c' + def test_nem_signtx_multiple_mosaics(self): self.setup_mnemonic_nopin_nopassphrase() From 7cfbe689e8f9e4448c7bc229baf8f8a3783bc606 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Wed, 25 Apr 2018 12:52:32 +0100 Subject: [PATCH 57/57] tests/device/nem: different amounts; note about what is displayed --- .../test_msg_nem_signtx_transfers.py | 53 +++++++++++-------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py b/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py index 1f52b8b972..0a710fbea4 100644 --- a/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py +++ b/trezorlib/tests/device_tests/test_msg_nem_signtx_transfers.py @@ -98,16 +98,11 @@ class TestMsgNEMSignTx(TrezorTest): assert len(tx.signature) == 64 def test_nem_signtx_xem_as_mosaic(self): - # tx hash: 9f8741194576a090bc71a3f43a03855950f94278fa121e99203e45967e19a7d0 - signature = unhexlify( - "1bca7b1b9ffb16d2c2adffa665be072bd2d7a0eafe4a9911dc473500c272905edf3d626274deb52aa490137a276d1fca67ee487079ebf9c09f9faa414f8e7c02" - ) - self.setup_mnemonic_nopin_nopassphrase() tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 76809215, - "amount": 1000000, + "amount": 5000000, "fee": 1000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "type": nem.TYPE_TRANSACTION_TRANSFER, @@ -121,20 +116,21 @@ class TestMsgNEMSignTx(TrezorTest): "namespaceId": "nem", "name": "xem", }, - "quantity": 1000000, + "quantity": 9000000, }, ], }) - assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000010000001a0000000e000000030000006e656d0300000078656d40420f0000000000' - assert tx.signature == signature + # trezor should display 45 XEM (multiplied by amount) + assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a404b4c000000000000000000010000001a0000000e000000030000006e656d0300000078656d4054890000000000' + assert hexlify(tx.signature) == b'7b25a84b65adb489ea55739f1ca2d83a0ae069c3c58d0ea075fc30bfe8f649519199ad2324ca229c6c3214191469f95326e99712124592cae7cd3a092c93ac0c' def test_nem_signtx_unknown_mosaic(self): self.setup_mnemonic_nopin_nopassphrase() tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 76809215, - "amount": 1000000, + "amount": 2000000, "fee": 1000000, "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "type": nem.TYPE_TRANSACTION_TRANSFER, @@ -148,13 +144,14 @@ class TestMsgNEMSignTx(TrezorTest): "namespaceId": "xxx", "name": "aa", }, - "quantity": 1000000, + "quantity": 3500000, }, ], }) - assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f00000000000000000001000000190000000d0000000300000078787802000000616140420f0000000000' - assert hexlify(tx.signature) == b'4394067992b44692fbba761ea7cc6646959df1122efef46e23ebaa0c061bf7a5221ca014a2a32889dc9f7fc56a2440595f11944900809452e81166a6e6784e01' + # trezor should display warning about unknown mosaic and then dialog for 7000000 raw units of xxx.aa and 0 XEM + assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e00000000000000000001000000190000000d00000003000000787878020000006161e067350000000000' + assert hexlify(tx.signature) == b'2f0280420eceb41ef9e5d94fa44ddda9cdc70b8f423ae18af577f6d85df64bb4aaf40cf24fc6eef47c63b0963611f8682348cecdc49a9b64eafcbe7afcb49102' def test_nem_signtx_known_mosaic(self): @@ -162,7 +159,7 @@ class TestMsgNEMSignTx(TrezorTest): tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 76809215, - "amount": 9876543, + "amount": 3000000, "fee": 1000000, "recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT", "type": nem.TYPE_TRANSACTION_TRANSFER, @@ -176,25 +173,26 @@ class TestMsgNEMSignTx(TrezorTest): "namespaceId": "dim", "name": "token", }, - "quantity": 1230009, + "quantity": 111000, }, ], }) - assert hexlify(tx.data) == b'0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c543fb496000000000000000000010000001c000000100000000300000064696d05000000746f6b656eb9c4120000000000' - assert hexlify(tx.signature) == b'b8dea33a8d654f190fe4d8455537869da6a707b710a38b00882bf3e5d8b5001285c34a2e5eca9cfe80c6908c38a5f9e6b2be15d327bdc6215e7350c541e1600c' + # trezor should display 0 XEM and 0.333 DIMTOK + assert hexlify(tx.data) == b'0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c54c0c62d000000000000000000010000001c000000100000000300000064696d05000000746f6b656e98b1010000000000' + assert hexlify(tx.signature) == b'e7f14ef8c39727bfd257e109cd5acac31542f2e41f2e5deb258fc1db602b690eb1cabca41a627fe2adc51f3193db85c76b41c80bb60161eb8738ebf20b507104' def test_nem_signtx_multiple_mosaics(self): self.setup_mnemonic_nopin_nopassphrase() tx = self.client.nem_sign_tx(self.client.expand_path("m/44'/1'/0'/0'/0'"), { "timeStamp": 76809215, - "amount": 1000000, + "amount": 2000000, "fee": 1000000, - "recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", + "recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT", "type": nem.TYPE_TRANSACTION_TRANSFER, "deadline": 76895615, - "version": (0x98 << 24), + "version": (0x68 << 24), "message": { }, "mosaics": [ @@ -203,7 +201,7 @@ class TestMsgNEMSignTx(TrezorTest): "namespaceId": "nem", "name": "xem", }, - "quantity": 1000000, + "quantity": 3000000, }, { "mosaicId": { @@ -226,8 +224,17 @@ class TestMsgNEMSignTx(TrezorTest): }, "quantity": 2000000, }, + { + "mosaicId": { + "namespaceId": "breeze", + "name": "breeze-token", + }, + "quantity": 111000, + } ] }) - assert hexlify(tx.data) == b'0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a40420f000000000000000000020000001d0000001100000003000000616263060000006d6f7361696348851e00000000001a0000000e000000030000006e656d0300000078656d70b70f0000000000' - assert hexlify(tx.signature) == b'c83dec432a791733a79647a30c4c1bb38b27379768f9164cf5c53473078368f3bd9547049882b41ebb90edd1d4eef618cc0293af85d8166f26f3768a3c0b9802' + # trezor should display warning, 6.06 XEM, 4000400 raw units of abc.mosaic (mosaics are merged) + # and 222000 BREEZE + assert hexlify(tx.data) == b'0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000030000001d0000001100000003000000616263060000006d6f7361696348851e0000000000260000001a00000006000000627265657a650c000000627265657a652d746f6b656e98b10100000000001a0000000e000000030000006e656d0300000078656df03b2e0000000000' + assert hexlify(tx.signature) == b'b2b9319fca87a05bee17108edd9a8f78aeffef74bf6b4badc6da5d46e8ff4fe82e24bf69d8e6c4097d072adf39d0c753e7580f8afb21e3288ebfb7c4d84e470d'