From 19097c7bf20c9be8094afba51b08f8182b1a3098 Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Tue, 15 Jul 2025 15:18:36 +0800 Subject: [PATCH] [WIP] feat(tron): add TransferContract support. - Squashes the `chore: add Capability_Tron` to its preceding commit from #5359 - Allows native transfer of TRX - Adds sign and TransferContract support [no changelog] Co-authored-by: PrisionMike --- common/defs/misc/misc.json | 7 + common/protob/messages-management.proto | 1 + common/protob/messages-tron.proto | 88 +- common/protob/messages.proto | 4 + common/tests/fixtures/tron/sign_tx.json | 220 ++ core/embed/upymod/qstrdefsport.h | 7 + core/src/apps/base.py | 1 + core/src/apps/tron/consts.py | 31 + core/src/apps/tron/converter.py | 18 + core/src/apps/tron/helpers.py | 11 +- core/src/apps/tron/layout.py | 29 + core/src/apps/tron/sign_tx.py | 99 + core/src/apps/workflow_handlers.py | 2 + core/src/trezor/enums/Capability.py | 1 + core/src/trezor/enums/MessageType.py | 4 + core/src/trezor/enums/TronRawContractType.py | 5 + core/src/trezor/enums/__init__.py | 8 + core/src/trezor/messages.py | 141 ++ core/src/trezor/ui/layouts/bolt/__init__.py | 17 + core/src/trezor/ui/layouts/caesar/__init__.py | 18 + .../src/trezor/ui/layouts/delizia/__init__.py | 17 + .../src/trezor/ui/layouts/eckhart/__init__.py | 17 + python/src/trezorlib/cli/tron.py | 21 + python/src/trezorlib/messages.py | 165 ++ python/src/trezorlib/tron.py | 63 +- rust/trezor-client/src/messages/generated.rs | 4 + .../src/protos/generated/messages.rs | 60 +- .../protos/generated/messages_management.rs | 239 +- .../src/protos/generated/messages_tron.rs | 2103 ++++++++++++++++- tests/device_tests/tron/test_sign_tx.py | 33 + 30 files changed, 3292 insertions(+), 142 deletions(-) create mode 100644 common/tests/fixtures/tron/sign_tx.json create mode 100644 core/src/apps/tron/consts.py create mode 100644 core/src/apps/tron/converter.py create mode 100644 core/src/apps/tron/layout.py create mode 100644 core/src/apps/tron/sign_tx.py create mode 100644 core/src/trezor/enums/TronRawContractType.py create mode 100644 tests/device_tests/tron/test_sign_tx.py diff --git a/common/defs/misc/misc.json b/common/defs/misc/misc.json index dbd09766d8c..78ada11b121 100644 --- a/common/defs/misc/misc.json +++ b/common/defs/misc/misc.json @@ -103,5 +103,12 @@ "slip44": 501, "curve": "ed25519", "decimals": 9 + }, + { + "name": "Tron", + "shortcut": "TRX", + "slip44": 195, + "curve": "secp256k1", + "decimals": 6 } ] diff --git a/common/protob/messages-management.proto b/common/protob/messages-management.proto index 398d84cb691..c65c5deeca2 100644 --- a/common/protob/messages-management.proto +++ b/common/protob/messages-management.proto @@ -174,6 +174,7 @@ message Features { Capability_Haptic = 21 [(bitcoin_only) = true]; Capability_BLE = 22 [(bitcoin_only) = true]; // Bluetooth Low Energy Capability_NFC = 23 [(bitcoin_only) = true]; // Near Field Communications + Capability_Tron = 24; } } diff --git a/common/protob/messages-tron.proto b/common/protob/messages-tron.proto index ddcfb0844a1..afd190f0cb6 100644 --- a/common/protob/messages-tron.proto +++ b/common/protob/messages-tron.proto @@ -12,9 +12,9 @@ option java_outer_classname = "TrezorMessageTron"; * @next Failure */ message TronGetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bool show_display = 2; // Optionally show on display before sending the result - optional bool chunkify = 3; // display the address in chunks of 4 characters + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // Optionally show on display before sending the result + optional bool chunkify = 3; // display the address in chunks of 4 characters } /** @@ -22,6 +22,86 @@ message TronGetAddress { * @end */ message TronAddress { - required string address = 1; // Tron address in base58_checked encoding + required string address = 1; // Tron address in Base32 encoding optional bytes mac = 2; // Address authentication code } + +/** + * Request: ask device to sign Stellar transaction + * @start + * @next StellarTxOpRequest + */ +message TronSignTx { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + required bytes ref_block_bytes = 2; // The height of the transaction reference block, using the 6th to 8th (exclusive) bytes of the reference block height, a total of 2 bytes + required bytes ref_block_hash = 3; // The hash of the transaction reference block + required sint64 expiration = 4; // Transaction expiration time, beyond which the transaction will no longer be packed + optional bytes data = 5; // Transaction memo. (256 bytes maximum, this is a Trezor limitation, not a Tron protocol limitation) + required sint64 timestamp = 6; // Transaction timestamp, set as the transaction creation time + optional sint64 fee_limit = 7; // The maximum energy cost allowed for the execution of smart contract transactions. Only deploying and triggering smart contract transactions need to be set, others not +} + +/** + * Response: device is ready for client to send the next operation + * @next TronTransferContract + */ +message TronContractRequest { +} + +/** + * Request: ask device to confirm this operation type + * @next TronSignature + */ +message TronTransferContract { + // https://developers.tron.network/docs/tron-contracttype#2-transfercontract + required string owner_address = 1; // Sender's address, base58_checked encoding + required string to_address = 2; // Recipient's address, base58_checked encoding + required sint64 amount = 3; // Transfer amount (in SUN) +} + +/** + * Response: signature for transaction + * @end + */ +message TronSignature { + required bytes signature = 1; // Signature of the transaction +} + + +/** + * TronRawTransaction and embedded messages are used to encode the Tron transaction, not for communication. + * @start + * @end + */ +// https://github.com/tronprotocol/protocol/blob/37bb922a9967bbbef1e84de1c9e5cda56a2d7998/core/Tron.proto#L431-L445 +message TronRawTransaction { + required bytes ref_block_bytes = 1; + required bytes ref_block_hash = 4; + required uint64 expiration = 8; + optional bytes data = 10; + repeated TronRawContract contract = 11; + required uint64 timestamp = 14; + optional uint64 fee_limit = 18; + + // https://github.com/tronprotocol/protocol/blob/37bb922a9967bbbef1e84de1c9e5cda56a2d7998/core/Tron.proto#L337-L385 + message TronRawContract { + // https://github.com/tronprotocol/protocol/blob/37bb922a9967bbbef1e84de1c9e5cda56a2d7998/core/contract/balance_contract.proto#L32-L36 + message TronRawTransferContract { + required bytes owner_address = 1; + required bytes to_address = 2; + required uint64 amount = 3; + } + + message TronRawParameter { + required string type_url = 1; // e.g., "type.googleapis.com/protocol.TransferContract" + required bytes value = 2; // The serialized value of the contract parameter, e.g., TronTransferContract + } + + required TronRawContractType type = 1; + required TronRawParameter parameter = 2; + + enum TronRawContractType { + TransferContract = 1; + } + } +} diff --git a/common/protob/messages.proto b/common/protob/messages.proto index 3faa7c7cec2..62793485d8a 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -351,6 +351,10 @@ enum MessageType { // Tron MessageType_TronGetAddress = 2200 [(wire_in) = true]; MessageType_TronAddress = 2201 [(wire_out) = true]; + MessageType_TronSignTx = 2202 [(wire_in) = true]; + MessageType_TronSignature = 2203 [(wire_out) = true]; + MessageType_TronContractRequest = 2204 [(wire_out) = true]; + MessageType_TronTransferContract = 2205 [(wire_in) = true]; // Benchmark MessageType_BenchmarkListNames = 9100 [(bitcoin_only) = true]; diff --git a/common/tests/fixtures/tron/sign_tx.json b/common/tests/fixtures/tron/sign_tx.json new file mode 100644 index 00000000000..6831e7784e4 --- /dev/null +++ b/common/tests/fixtures/tron/sign_tx.json @@ -0,0 +1,220 @@ +{ + "comment": "raw field is used only for debugging.", + "setup": { + "mnemonic": "all all all all all all all all all all all all", + "passphrase": "" + }, + "tests": [ + { + "name": "TransferContract", + "parameters": { + "address_n": "m/44'/195'/0'/0/0", + "tx": { + "ref_block_bytes": "e942", + "ref_block_hash": "6394747da9fee421", + "expiration": 1752562632000, + "timestamp": 1752562572000 + }, + "contract": { + "_message_type": "TronTransferContract", + "owner_address": "TY72iA3SBtrds3QLYsS7LwYfkzXwAXCRWT", + "to_address": "TFz2CJn9CJb8C4i1Gke3jmZX2fRMJxniH2", + "amount": 18123456 + }, + "raw_data_hex": "0a02e94222086394747da9fee42140c08afee680335a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d20870e0b5fae68033", + "raw": { + "visible": false, + "txID": "91813c4e057a4c881d9dc4981f041c33cffb17c41e860a53eb68e7995f5de821", + "raw_data_hex": "0a02e94222086394747da9fee42140c08afee680335a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d20870e0b5fae68033", + "raw_data": { + "contract": [ + { + "parameter": { + "value": { + "to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283", + "owner_address": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58", + "amount": 18123456 + }, + "type_url": "type.googleapis.com/protocol.TransferContract" + }, + "type": "TransferContract" + } + ], + "ref_block_bytes": "e942", + "ref_block_hash": "6394747da9fee421", + "expiration": 1752562632000, + "timestamp": 1752562572000 + } + } + }, + "result": { + "signature": "a7f8602b02413e9dded0170daa5b4ada9a2679198af276be456f4faea1bc326f5070789bec5e6471de3f726f4fe0c9daced8df183e4a62804db26d5650c59a521C" + } + }, + { + "name": "TransferContract_owner_address_not_equals_trezor_account", + "parameters": { + "address_n": "m/44'/195'/0'/0/1", + "tx": { + "ref_block_bytes": "e942", + "ref_block_hash": "6394747da9fee421", + "expiration": 1752562632000, + "timestamp": 1752562572000 + }, + "contract": { + "_message_type": "TronTransferContract", + "owner_address": "TY72iA3SBtrds3QLYsS7LwYfkzXwAXCRWT", + "to_address": "TFz2CJn9CJb8C4i1Gke3jmZX2fRMJxniH2", + "amount": 18123456 + }, + "raw_data_hex": "0a02e94222086394747da9fee42140c08afee680335a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d20870e0b5fae68033", + "raw": { + "visible": false, + "txID": "91813c4e057a4c881d9dc4981f041c33cffb17c41e860a53eb68e7995f5de821", + "raw_data_hex": "0a02e94222086394747da9fee42140c08afee680335a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d20870e0b5fae68033", + "raw_data": { + "contract": [ + { + "parameter": { + "value": { + "to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283", + "owner_address": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58", + "amount": 18123456 + }, + "type_url": "type.googleapis.com/protocol.TransferContract" + }, + "type": "TransferContract" + } + ], + "ref_block_bytes": "e942", + "ref_block_hash": "6394747da9fee421", + "expiration": 1752562632000, + "timestamp": 1752562572000 + } + } + }, + "result": { + "signature": "14d5eae24e33eb6af03998ea845f98e105e8a2d3206b12163b11702ed3479f41719f757c50e2d85ab6b41ff28ce9752a6bbb74158b8a1aaffb44a837466d93ba1B" + } + }, + { + "name": "TransferContract_amount_int64_max", + "parameters": { + "address_n": "m/44'/195'/0'/0/0", + "tx": { + "ref_block_bytes": "0fc4", + "ref_block_hash": "9643b084bc8b5cde", + "expiration": 1752568944000, + "timestamp": 1752571244333 + }, + "contract": { + "_message_type": "TronTransferContract", + "owner_address": "TY72iA3SBtrds3QLYsS7LwYfkzXwAXCRWT", + "to_address": "TFz2CJn9CJb8C4i1Gke3jmZX2fRMJxniH2", + "amount": 9223372036854775807 + }, + "raw_data_hex": "0a020fc422089643b084bc8b5cde4080abffe980335a6d080112690a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412380a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318ffffffffffffffff7f70adde8beb8033", + "comment": "tornweb JavaScript SDK does not support big integers" + }, + "result": { + "signature": "36db819a6c50b8c770ff1067a2753692fa8c8bfa7efde8ddfc2f891f7053d9955f6ffd0ee7d6217b448ac3515d97f6877159b721f2a78da78d1fcc10c1019dd51b" + } + }, + { + "name": "Memo_hello_world", + "parameters": { + "address_n": "m/44'/195'/0'/0/0", + "tx": { + "ref_block_bytes": "ea2a", + "ref_block_hash": "d43320ee5a8b677f", + "expiration": 1752563334000, + "timestamp": 1752563274000, + "data": "68656c6c6f20776f726c6421" + }, + "contract": { + "_message_type": "TronTransferContract", + "owner_address": "TY72iA3SBtrds3QLYsS7LwYfkzXwAXCRWT", + "to_address": "TFz2CJn9CJb8C4i1Gke3jmZX2fRMJxniH2", + "amount": 18123456 + }, + "raw_data_hex": "0a02ea2a2208d43320ee5a8b677f40f0f6a8e78033520c68656c6c6f20776f726c64215a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d2087090a2a5e78033", + "raw": { + "txID": "2b166e72fe1cfb71345d5061d15e10ac2cc5ee3bb85b5ad34a14c9bf112b8372", + "raw_data": { + "data": "68656c6c6f20776f726c6421", + "contract": [ + { + "parameter": { + "value": { + "amount": 18123456, + "owner_address": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58", + "to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283" + }, + "type_url": "type.googleapis.com/protocol.TransferContract" + }, + "type": "TransferContract" + } + ], + "ref_block_bytes": "ea2a", + "ref_block_hash": "d43320ee5a8b677f", + "expiration": 1752563334000, + "timestamp": 1752563274000 + }, + "raw_data_hex": "0a02ea2a2208d43320ee5a8b677f40f0f6a8e78033520c68656c6c6f20776f726c64215a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d2087090a2a5e78033", + "visible": false + } + }, + "result": { + "signature": "7b43c3e8977db4f5475656eec2e643bf1549d923f29c28c009c85b51556a78602aa0f3f2780cb19655dfa8d4eb2102a3c6b3440ce5b7448a814c860cdc925dd21C" + } + }, + { + "name": "Memo_long_hex_string", + "parameters": { + "address_n": "m/44'/195'/0'/0/0", + "tx": { + "ref_block_bytes": "ea54", + "ref_block_hash": "e5ae03970dae489a", + "expiration": 1752563466000, + "timestamp": 1752563406000, + "data": "e7fb3e7e39d4c650449e8d80c2731c4cc7fe0c7888a189a6eb1ead3621729a3ae8578299b2a1a35edf5ce3d9ae732cc4f202a34304900156ab37a78917609ae58dae01cb4de5ed98ff79a56e7f0e41f6042d3a734ae3b438209294a8a1899ddd4dee47c1cc86a0b2bf7d57d8457dfeed5fc2a24cd553c08a831f10a02ce5fb776d287e71e6a1a899ae966a0928f01ce6d3c4b0ee5151872c6dd80fefbfb79cff1949bfb5aba76b624e4c58eadf6c8ad97680e34d50807dc628dce44b39f3f405d5da406eb109cabdfc8c782be22f39c2e8814946e69977781fd66c691416b2785f41b508db37e819257751ee97794a57d7a8db5fb4b2cfce6031b76874922010" + }, + "contract": { + "_message_type": "TronTransferContract", + "owner_address": "TY72iA3SBtrds3QLYsS7LwYfkzXwAXCRWT", + "to_address": "TFz2CJn9CJb8C4i1Gke3jmZX2fRMJxniH2", + "amount": 18123456 + }, + "raw_data_hex": "0a02ea542208e5ae03970dae489a4090feb0e78033528002e7fb3e7e39d4c650449e8d80c2731c4cc7fe0c7888a189a6eb1ead3621729a3ae8578299b2a1a35edf5ce3d9ae732cc4f202a34304900156ab37a78917609ae58dae01cb4de5ed98ff79a56e7f0e41f6042d3a734ae3b438209294a8a1899ddd4dee47c1cc86a0b2bf7d57d8457dfeed5fc2a24cd553c08a831f10a02ce5fb776d287e71e6a1a899ae966a0928f01ce6d3c4b0ee5151872c6dd80fefbfb79cff1949bfb5aba76b624e4c58eadf6c8ad97680e34d50807dc628dce44b39f3f405d5da406eb109cabdfc8c782be22f39c2e8814946e69977781fd66c691416b2785f41b508db37e819257751ee97794a57d7a8db5fb4b2cfce6031b768749220105a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d20870b0a9ade78033", + "raw": { + "txID": "005fe60597b52c7d9e021795f084ca7da323f4fc08a406292443ce7a4d480dc5", + "raw_data": { + "data": "e7fb3e7e39d4c650449e8d80c2731c4cc7fe0c7888a189a6eb1ead3621729a3ae8578299b2a1a35edf5ce3d9ae732cc4f202a34304900156ab37a78917609ae58dae01cb4de5ed98ff79a56e7f0e41f6042d3a734ae3b438209294a8a1899ddd4dee47c1cc86a0b2bf7d57d8457dfeed5fc2a24cd553c08a831f10a02ce5fb776d287e71e6a1a899ae966a0928f01ce6d3c4b0ee5151872c6dd80fefbfb79cff1949bfb5aba76b624e4c58eadf6c8ad97680e34d50807dc628dce44b39f3f405d5da406eb109cabdfc8c782be22f39c2e8814946e69977781fd66c691416b2785f41b508db37e819257751ee97794a57d7a8db5fb4b2cfce6031b76874922010", + "contract": [ + { + "parameter": { + "value": { + "amount": 18123456, + "owner_address": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58", + "to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283" + }, + "type_url": "type.googleapis.com/protocol.TransferContract" + }, + "type": "TransferContract" + } + ], + "ref_block_bytes": "ea54", + "ref_block_hash": "e5ae03970dae489a", + "expiration": 1752563466000, + "timestamp": 1752563406000 + }, + "raw_data_hex": "0a02ea542208e5ae03970dae489a4090feb0e78033528002e7fb3e7e39d4c650449e8d80c2731c4cc7fe0c7888a189a6eb1ead3621729a3ae8578299b2a1a35edf5ce3d9ae732cc4f202a34304900156ab37a78917609ae58dae01cb4de5ed98ff79a56e7f0e41f6042d3a734ae3b438209294a8a1899ddd4dee47c1cc86a0b2bf7d57d8457dfeed5fc2a24cd553c08a831f10a02ce5fb776d287e71e6a1a899ae966a0928f01ce6d3c4b0ee5151872c6dd80fefbfb79cff1949bfb5aba76b624e4c58eadf6c8ad97680e34d50807dc628dce44b39f3f405d5da406eb109cabdfc8c782be22f39c2e8814946e69977781fd66c691416b2785f41b508db37e819257751ee97794a57d7a8db5fb4b2cfce6031b768749220105a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d20870b0a9ade78033", + "visible": false + } + }, + "result": { + "signature": "22cc2bf4942334a0ac8d5536f372cb514b0768b32abfa2fa9bdc16067e92ad8313f23848beb7d938134fe829ef2d46409e950b4dea7312977ff1e478b2e5b90a1B" + } + } + ] +} diff --git a/core/embed/upymod/qstrdefsport.h b/core/embed/upymod/qstrdefsport.h index b073ad18220..905047dfda8 100644 --- a/core/embed/upymod/qstrdefsport.h +++ b/core/embed/upymod/qstrdefsport.h @@ -486,6 +486,7 @@ Q(StellarMemoType) Q(StellarSignerType) Q(TezosBallotType) Q(TezosContractType) +Q(TronRawContractType) Q(account_path_check) Q(actions) Q(add_resident_credential) @@ -648,8 +649,12 @@ Q(apps.tezos.helpers) Q(apps.tezos.layout) Q(apps.tezos.sign_tx) Q(apps.tron) +Q(apps.tron.consts) +Q(apps.tron.converter) Q(apps.tron.get_address) Q(apps.tron.helpers) +Q(apps.tron.layout) +Q(apps.tron.sign_tx) Q(apps.webauthn) Q(apps.webauthn.add_resident_credential) Q(apps.webauthn.common) @@ -679,6 +684,7 @@ Q(clsag) Q(common) Q(constants) Q(consts) +Q(converter) Q(credential) Q(credentials) Q(crypto_helpers) @@ -785,6 +791,7 @@ Q(trezor.enums.StellarMemoType) Q(trezor.enums.StellarSignerType) Q(trezor.enums.TezosBallotType) Q(trezor.enums.TezosContractType) +Q(trezor.enums.TronRawContractType) Q(tron) Q(tx_ct_key) Q(tx_ecdh) diff --git a/core/src/apps/base.py b/core/src/apps/base.py index 8292fec4af2..a43d08d4d9b 100644 --- a/core/src/apps/base.py +++ b/core/src/apps/base.py @@ -131,6 +131,7 @@ def get_features() -> Features: Capability.Ripple, Capability.Stellar, Capability.Tezos, + Capability.Tron, Capability.U2F, Capability.Shamir, Capability.ShamirGroups, diff --git a/core/src/apps/tron/consts.py b/core/src/apps/tron/consts.py new file mode 100644 index 00000000000..1630415091f --- /dev/null +++ b/core/src/apps/tron/consts.py @@ -0,0 +1,31 @@ +from micropython import const +from typing import TYPE_CHECKING + +from trezor.enums import MessageType + +if TYPE_CHECKING: + from trezor.messages import TronTransferContract + + TronMessageType = TronTransferContract + +# Maximum length of the data field in TronSignTx. +MAX_DATA_LENGTH = const(256) + +# 1 SUN = 0.000001 TRX +TRX_AMOUNT_DECIMALS = const(6) + +TYPE_URL_TEMPLATE = "type.googleapis.com/protocol." + +contract_types = [MessageType.TronTransferContract] + +# https://github.com/tronprotocol/protocol/blob/37bb922a9967bbbef1e84de1c9e5cda56a2d7998/core/Tron.proto#L339-L379 +contract_type_names = { + 1: "TransferContract", +} + + +def get_contract_type_name(contract_type: int) -> str: + """Get contract type name by its number.""" + if contract_type in contract_type_names: + return contract_type_names[contract_type] + raise ValueError(f"Unknown contract type: {contract_type}") diff --git a/core/src/apps/tron/converter.py b/core/src/apps/tron/converter.py new file mode 100644 index 00000000000..ab4e55103d3 --- /dev/null +++ b/core/src/apps/tron/converter.py @@ -0,0 +1,18 @@ +from typing import TYPE_CHECKING + +from .helpers import decode_address + +if TYPE_CHECKING: + from trezor.messages import TronRawTransferContract, TronTransferContract + + +def convert_transfer_contract( + contract: TronTransferContract, +) -> TronRawTransferContract: + from trezor.messages import TronRawTransferContract + + return TronRawTransferContract( + owner_address=decode_address(contract.owner_address), + to_address=decode_address(contract.to_address), + amount=contract.amount, + ) diff --git a/core/src/apps/tron/helpers.py b/core/src/apps/tron/helpers.py index c7684e8816a..86dcddb84a2 100644 --- a/core/src/apps/tron/helpers.py +++ b/core/src/apps/tron/helpers.py @@ -1,7 +1,16 @@ from trezor.crypto import base58 -from trezor.crypto.hashlib import sha3_256 def address_from_public_key(pubkey: bytes) -> str: + from trezor.crypto.hashlib import sha3_256 + address_bytes = b"\x41" + sha3_256(pubkey[1:], keccak=True).digest()[12:] return base58.encode_check(address_bytes) + + +def decode_address(address: str) -> bytes: + """Decodes a Tron address into its raw bytes.""" + decoded = base58.decode_check(address) + if decoded[0] != 0x41: + raise ValueError("Invalid Tron address prefix") + return decoded diff --git a/core/src/apps/tron/layout.py b/core/src/apps/tron/layout.py new file mode 100644 index 00000000000..54ffe85b59a --- /dev/null +++ b/core/src/apps/tron/layout.py @@ -0,0 +1,29 @@ +from typing import TYPE_CHECKING + +import trezor.ui.layouts as layouts +from trezor import TR, strings + +from . import consts + +if TYPE_CHECKING: + from trezor.messages import TronTransferContract + + +def format_trx_amount(amount: int) -> str: + return f"{strings.format_amount(amount, consts.TRX_AMOUNT_DECIMALS)} TRX" + + +async def confirm_transfer_contract( + msg: TronTransferContract, trezor_account: str +) -> None: + if trezor_account != msg.owner_address: + # If the owner address is not the same as the Trezor account, we need to confirm the owner address. + # This may occur in scenarios involving multi-signatures. + # The `confirm_output` has a `source_account` field, but it does not work in T3B1; perhaps we should unify them. + await layouts.confirm_address( + TR.send__send_from, msg.owner_address, chunkify=False + ) + await layouts.confirm_output( + msg.to_address, + format_trx_amount(msg.amount), + ) diff --git a/core/src/apps/tron/sign_tx.py b/core/src/apps/tron/sign_tx.py new file mode 100644 index 00000000000..46bc94404ec --- /dev/null +++ b/core/src/apps/tron/sign_tx.py @@ -0,0 +1,99 @@ +from typing import TYPE_CHECKING + +from trezor.wire import DataError + +from apps.common.keychain import with_slip44_keychain + +from . import CURVE, PATTERN, SLIP44_ID, consts + +if TYPE_CHECKING: + from trezor.messages import TronRawContract, TronSignature, TronSignTx + + from apps.common.keychain import Keychain + + +@with_slip44_keychain(PATTERN, slip44_id=SLIP44_ID, curve=CURVE) +async def sign_tx(msg: TronSignTx, keychain: Keychain) -> TronSignature: + import trezor.messages as messages + from trezor import TR + from trezor.crypto.curve import secp256k1 + from trezor.crypto.hashlib import sha256 + from trezor.protobuf import dump_message_buffer + from trezor.ui.layouts import confirm_blob, confirm_tron_tx, show_continue_in_app + from trezor.wire.context import call_any + + from apps.common import paths + + from .helpers import address_from_public_key + + await paths.validate_path(keychain, msg.address_n) + node = keychain.derive(msg.address_n) + private_key = node.private_key() + public_key = secp256k1.publickey(node.private_key(), False) + trezor_address = address_from_public_key(public_key) + + if msg.data: + if len(msg.data) > consts.MAX_DATA_LENGTH: + raise DataError("Tron: data field too long") + await confirm_blob("confirm_memo", TR.words__memo, msg.data) + + # Currently, Tron transactions only support a single contract call, + # but they have defined the contract as a list for future expansion. + # https://github.com/tronprotocol/protocol/blob/37bb922a9967bbbef1e84de1c9e5cda56a2d7998/core/Tron.proto#L439-L440 + contract = await call_any(messages.TronContractRequest(), *consts.contract_types) + raw_contract, total_send = await process_contract(contract, trezor_address) # type: ignore [Argument of type "MessageType" cannot be assigned to parameter "contract" of type "TronMessageType" in function "process_contract"] + + # Regarding the TransferContract, the maximum fee is currently not calculated; + # I will research it further. + await confirm_tron_tx(total_send, TR.words__unknown) + + raw_tx = messages.TronRawTransaction( + ref_block_bytes=msg.ref_block_bytes, + ref_block_hash=msg.ref_block_hash, + expiration=msg.expiration, + data=msg.data, + contract=[raw_contract], + timestamp=msg.timestamp, + fee_limit=msg.fee_limit, + ) + serialized_tx = dump_message_buffer(raw_tx) + + w_hash = sha256(serialized_tx).digest() + signature = secp256k1.sign(private_key, w_hash, False) + v_val = signature[0] + 27 if signature[0] < 27 else signature[0] + signature = signature[1:] + bytes([v_val]) + + show_continue_in_app(TR.send__transaction_signed) + return messages.TronSignature(signature=signature) + + +async def process_contract( + contract: consts.TronMessageType, trezor_address: str +) -> tuple[TronRawContract, str]: + import trezor.messages as messages + from trezor.enums import TronRawContractType + from trezor.protobuf import dump_message_buffer + + from . import converter, layout + + total_send = parameter = contract_type = None + + if messages.TronTransferContract.is_type_of(contract): + contract_type = TronRawContractType.TransferContract + await layout.confirm_transfer_contract(contract, trezor_address) + parameter = converter.convert_transfer_contract(contract) + total_send = layout.format_trx_amount(contract.amount) + else: + raise DataError("Tron: contract type unknown") + + serialized_parameter = dump_message_buffer(parameter) + raw_contract = messages.TronRawContract( + type=contract_type, + parameter=messages.TronRawParameter( + type_url=consts.TYPE_URL_TEMPLATE + + consts.get_contract_type_name(contract_type), + value=serialized_parameter, + ), + ) + + return raw_contract, total_send diff --git a/core/src/apps/workflow_handlers.py b/core/src/apps/workflow_handlers.py index 4a8627390b6..41fd7d06090 100644 --- a/core/src/apps/workflow_handlers.py +++ b/core/src/apps/workflow_handlers.py @@ -226,6 +226,8 @@ def _find_message_handler_module(msg_type: int) -> str: # tron if msg_type == MessageType.TronGetAddress: return "apps.tron.get_address" + if msg_type == MessageType.TronSignTx: + return "apps.tron.sign_tx" raise ValueError diff --git a/core/src/trezor/enums/Capability.py b/core/src/trezor/enums/Capability.py index 91b2d692f86..e6adba33d8f 100644 --- a/core/src/trezor/enums/Capability.py +++ b/core/src/trezor/enums/Capability.py @@ -27,3 +27,4 @@ Tezos = 13 U2F = 14 Solana = 18 + Tron = 24 diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index 79a260057f6..8bdbf3e4f14 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -269,3 +269,7 @@ NostrEventSignature = 2004 TronGetAddress = 2200 TronAddress = 2201 + TronSignTx = 2202 + TronSignature = 2203 + TronContractRequest = 2204 + TronTransferContract = 2205 diff --git a/core/src/trezor/enums/TronRawContractType.py b/core/src/trezor/enums/TronRawContractType.py new file mode 100644 index 00000000000..49e3f49d4cd --- /dev/null +++ b/core/src/trezor/enums/TronRawContractType.py @@ -0,0 +1,5 @@ +# Automatically generated by pb2py +# fmt: off +# isort:skip_file + +TransferContract = 1 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index 6085a7289d1..eb7b8cafaa2 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -234,6 +234,7 @@ class Capability(IntEnum): Haptic = 21 BLE = 22 NFC = 23 + Tron = 24 class SdProtectOperationType(IntEnum): DISABLE = 0 @@ -370,6 +371,9 @@ class ThpPairingMethod(IntEnum): QrCode = 3 NFC = 4 + class TronRawContractType(IntEnum): + TransferContract = 1 + class MessageType(IntEnum): Initialize = 0 Ping = 1 @@ -631,6 +635,10 @@ class MessageType(IntEnum): EvoluDelegatedIdentityKey = 2105 TronGetAddress = 2200 TronAddress = 2201 + TronSignTx = 2202 + TronSignature = 2203 + TronContractRequest = 2204 + TronTransferContract = 2205 BenchmarkListNames = 9100 BenchmarkNames = 9101 BenchmarkRun = 9102 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index b0fdaa2c0fc..36747e8e519 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -69,6 +69,7 @@ def __getattr__(name: str) -> Any: from trezor.enums import TezosContractType # noqa: F401 from trezor.enums import ThpMessageType # noqa: F401 from trezor.enums import ThpPairingMethod # noqa: F401 + from trezor.enums import TronRawContractType # noqa: F401 from trezor.enums import WordRequestType # noqa: F401 class BenchmarkListNames(protobuf.MessageType): @@ -6811,6 +6812,146 @@ def __init__( def is_type_of(cls, msg: Any) -> TypeGuard["TronAddress"]: return isinstance(msg, cls) + class TronSignTx(protobuf.MessageType): + address_n: "list[int]" + ref_block_bytes: "AnyBytes" + ref_block_hash: "AnyBytes" + expiration: "int" + data: "AnyBytes | None" + timestamp: "int" + fee_limit: "int | None" + + def __init__( + self, + *, + ref_block_bytes: "AnyBytes", + ref_block_hash: "AnyBytes", + expiration: "int", + timestamp: "int", + address_n: "list[int] | None" = None, + data: "AnyBytes | None" = None, + fee_limit: "int | None" = None, + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["TronSignTx"]: + return isinstance(msg, cls) + + class TronContractRequest(protobuf.MessageType): + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["TronContractRequest"]: + return isinstance(msg, cls) + + class TronTransferContract(protobuf.MessageType): + owner_address: "str" + to_address: "str" + amount: "int" + + def __init__( + self, + *, + owner_address: "str", + to_address: "str", + amount: "int", + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["TronTransferContract"]: + return isinstance(msg, cls) + + class TronSignature(protobuf.MessageType): + signature: "AnyBytes" + + def __init__( + self, + *, + signature: "AnyBytes", + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["TronSignature"]: + return isinstance(msg, cls) + + class TronRawTransaction(protobuf.MessageType): + ref_block_bytes: "AnyBytes" + ref_block_hash: "AnyBytes" + expiration: "int" + data: "AnyBytes | None" + contract: "list[TronRawContract]" + timestamp: "int" + fee_limit: "int | None" + + def __init__( + self, + *, + ref_block_bytes: "AnyBytes", + ref_block_hash: "AnyBytes", + expiration: "int", + timestamp: "int", + contract: "list[TronRawContract] | None" = None, + data: "AnyBytes | None" = None, + fee_limit: "int | None" = None, + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["TronRawTransaction"]: + return isinstance(msg, cls) + + class TronRawContract(protobuf.MessageType): + type: "TronRawContractType" + parameter: "TronRawParameter" + + def __init__( + self, + *, + type: "TronRawContractType", + parameter: "TronRawParameter", + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["TronRawContract"]: + return isinstance(msg, cls) + + class TronRawTransferContract(protobuf.MessageType): + owner_address: "AnyBytes" + to_address: "AnyBytes" + amount: "int" + + def __init__( + self, + *, + owner_address: "AnyBytes", + to_address: "AnyBytes", + amount: "int", + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["TronRawTransferContract"]: + return isinstance(msg, cls) + + class TronRawParameter(protobuf.MessageType): + type_url: "str" + value: "AnyBytes" + + def __init__( + self, + *, + type_url: "str", + value: "AnyBytes", + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["TronRawParameter"]: + return isinstance(msg, cls) + class WebAuthnListResidentCredentials(protobuf.MessageType): @classmethod diff --git a/core/src/trezor/ui/layouts/bolt/__init__.py b/core/src/trezor/ui/layouts/bolt/__init__.py index 81a8442cf46..b792dcc4ce5 100644 --- a/core/src/trezor/ui/layouts/bolt/__init__.py +++ b/core/src/trezor/ui/layouts/bolt/__init__.py @@ -1448,6 +1448,23 @@ async def confirm_stellar_output( chunkify=False, ) + def confirm_tron_tx( + amount: str, + fee: str, + ) -> Awaitable[None]: + amount_title = f"{TR.send__total_amount}:" + fee_title = TR.send__maximum_fee + + return _confirm_summary( + amount, + amount_title, + fee, + fee_title, + extra_items=None, + br_name="confirm_tron_tx", + br_code=ButtonRequestType.SignTx, + ) + def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]: return raise_if_not_confirmed( diff --git a/core/src/trezor/ui/layouts/caesar/__init__.py b/core/src/trezor/ui/layouts/caesar/__init__.py index 893a00323ba..0e297c38ff7 100644 --- a/core/src/trezor/ui/layouts/caesar/__init__.py +++ b/core/src/trezor/ui/layouts/caesar/__init__.py @@ -1375,6 +1375,24 @@ def confirm_cardano_tx( br_code=ButtonRequestType.SignTx, ) + def confirm_tron_tx( + amount: str, + fee: str, + ) -> Awaitable[None]: + amount_title = f"{TR.send__total_amount}:" + fee_title = TR.send__maximum_fee + + return raise_if_cancelled( + trezorui_api.confirm_summary( + amount=amount, + amount_label=amount_title, + fee=fee, + fee_label=fee_title, + ), + br_name="confirm_cardano_tx", + br_code=ButtonRequestType.SignTx, + ) + async def confirm_ethereum_tx( recipient: str | None, total_amount: str, diff --git a/core/src/trezor/ui/layouts/delizia/__init__.py b/core/src/trezor/ui/layouts/delizia/__init__.py index aebbdf8a739..ac55a022850 100644 --- a/core/src/trezor/ui/layouts/delizia/__init__.py +++ b/core/src/trezor/ui/layouts/delizia/__init__.py @@ -1384,6 +1384,23 @@ async def confirm_stellar_output( chunkify=False, ) + def confirm_tron_tx( + amount: str, + fee: str, + ) -> Awaitable[None]: + amount_title = TR.send__total_amount + fee_title = TR.send__maximum_fee + + return _confirm_summary( + amount, + amount_title, + fee, + fee_title, + extra_items=None, + br_name="confirm_tron_tx", + br_code=ButtonRequestType.SignTx, + ) + def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]: return _confirm_summary( diff --git a/core/src/trezor/ui/layouts/eckhart/__init__.py b/core/src/trezor/ui/layouts/eckhart/__init__.py index 1ddc8c974e4..3cbeeb1f117 100644 --- a/core/src/trezor/ui/layouts/eckhart/__init__.py +++ b/core/src/trezor/ui/layouts/eckhart/__init__.py @@ -1409,6 +1409,23 @@ async def confirm_stellar_output( chunkify=False, ) + def confirm_tron_tx( + amount: str, + fee: str, + ) -> Awaitable[None]: + amount_title = TR.send__total_amount + fee_title = TR.send__maximum_fee + + return _confirm_summary( + amount, + amount_title, + fee, + fee_title, + extra_items=None, + br_name="confirm_tron_tx", + br_code=ButtonRequestType.SignTx, + ) + def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]: return _confirm_summary( diff --git a/python/src/trezorlib/cli/tron.py b/python/src/trezorlib/cli/tron.py index 9a2847b0fa6..d662a8d8cac 100644 --- a/python/src/trezorlib/cli/tron.py +++ b/python/src/trezorlib/cli/tron.py @@ -33,3 +33,24 @@ def get_address( """Get Tron address""" address_n = tools.parse_path(address) return tron.get_address(session, address_n, show_display, chunkify) + + +@cli.command() +@click.option( + "-n", + "--address", + required=False, + help=PATH_HELP, + default=tron.DEFAULT_BIP32_PATH, +) +@click.argument("raw_data_hex", type=str) +@with_client +def sign_tx(client: "TrezorClient", raw_data_hex: str, address: str) -> str: + """Sign a raw transaction.""" + + raw_data = bytes.fromhex(raw_data_hex) + tx, contract = tron.from_raw_data(raw_data) + address_n = tools.parse_path(address) + signed_tx = tron.sign_tx(client, tx, contract, address_n) + + return signed_tx.signature.hex() diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 9d01be3a98c..6df560612f9 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -263,6 +263,7 @@ class Capability(IntEnum): Haptic = 21 BLE = 22 NFC = 23 + Tron = 24 class SdProtectOperationType(IntEnum): @@ -423,6 +424,10 @@ class ThpPairingMethod(IntEnum): NFC = 4 +class TronRawContractType(IntEnum): + TransferContract = 1 + + class MessageType(IntEnum): Initialize = 0 Ping = 1 @@ -684,6 +689,10 @@ class MessageType(IntEnum): EvoluDelegatedIdentityKey = 2105 TronGetAddress = 2200 TronAddress = 2201 + TronSignTx = 2202 + TronSignature = 2203 + TronContractRequest = 2204 + TronTransferContract = 2205 BenchmarkListNames = 9100 BenchmarkNames = 9101 BenchmarkRun = 9102 @@ -8595,6 +8604,162 @@ def __init__( self.mac = mac +class TronSignTx(protobuf.MessageType): + MESSAGE_WIRE_TYPE = 2202 + FIELDS = { + 1: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None), + 2: protobuf.Field("ref_block_bytes", "bytes", repeated=False, required=True), + 3: protobuf.Field("ref_block_hash", "bytes", repeated=False, required=True), + 4: protobuf.Field("expiration", "sint64", repeated=False, required=True), + 5: protobuf.Field("data", "bytes", repeated=False, required=False, default=None), + 6: protobuf.Field("timestamp", "sint64", repeated=False, required=True), + 7: protobuf.Field("fee_limit", "sint64", repeated=False, required=False, default=None), + } + + def __init__( + self, + *, + ref_block_bytes: "bytes", + ref_block_hash: "bytes", + expiration: "int", + timestamp: "int", + address_n: Optional[Sequence["int"]] = None, + data: Optional["bytes"] = None, + fee_limit: Optional["int"] = None, + ) -> None: + self.address_n: Sequence["int"] = address_n if address_n is not None else [] + self.ref_block_bytes = ref_block_bytes + self.ref_block_hash = ref_block_hash + self.expiration = expiration + self.timestamp = timestamp + self.data = data + self.fee_limit = fee_limit + + +class TronContractRequest(protobuf.MessageType): + MESSAGE_WIRE_TYPE = 2204 + + +class TronTransferContract(protobuf.MessageType): + MESSAGE_WIRE_TYPE = 2205 + FIELDS = { + 1: protobuf.Field("owner_address", "string", repeated=False, required=True), + 2: protobuf.Field("to_address", "string", repeated=False, required=True), + 3: protobuf.Field("amount", "sint64", repeated=False, required=True), + } + + def __init__( + self, + *, + owner_address: "str", + to_address: "str", + amount: "int", + ) -> None: + self.owner_address = owner_address + self.to_address = to_address + self.amount = amount + + +class TronSignature(protobuf.MessageType): + MESSAGE_WIRE_TYPE = 2203 + FIELDS = { + 1: protobuf.Field("signature", "bytes", repeated=False, required=True), + } + + def __init__( + self, + *, + signature: "bytes", + ) -> None: + self.signature = signature + + +class TronRawTransaction(protobuf.MessageType): + MESSAGE_WIRE_TYPE = None + FIELDS = { + 1: protobuf.Field("ref_block_bytes", "bytes", repeated=False, required=True), + 4: protobuf.Field("ref_block_hash", "bytes", repeated=False, required=True), + 8: protobuf.Field("expiration", "uint64", repeated=False, required=True), + 10: protobuf.Field("data", "bytes", repeated=False, required=False, default=None), + 11: protobuf.Field("contract", "TronRawContract", repeated=True, required=False, default=None), + 14: protobuf.Field("timestamp", "uint64", repeated=False, required=True), + 18: protobuf.Field("fee_limit", "uint64", repeated=False, required=False, default=None), + } + + def __init__( + self, + *, + ref_block_bytes: "bytes", + ref_block_hash: "bytes", + expiration: "int", + timestamp: "int", + contract: Optional[Sequence["TronRawContract"]] = None, + data: Optional["bytes"] = None, + fee_limit: Optional["int"] = None, + ) -> None: + self.contract: Sequence["TronRawContract"] = contract if contract is not None else [] + self.ref_block_bytes = ref_block_bytes + self.ref_block_hash = ref_block_hash + self.expiration = expiration + self.timestamp = timestamp + self.data = data + self.fee_limit = fee_limit + + +class TronRawContract(protobuf.MessageType): + MESSAGE_WIRE_TYPE = None + FIELDS = { + 1: protobuf.Field("type", "TronRawContractType", repeated=False, required=True), + 2: protobuf.Field("parameter", "TronRawParameter", repeated=False, required=True), + } + + def __init__( + self, + *, + type: "TronRawContractType", + parameter: "TronRawParameter", + ) -> None: + self.type = type + self.parameter = parameter + + +class TronRawTransferContract(protobuf.MessageType): + MESSAGE_WIRE_TYPE = None + FIELDS = { + 1: protobuf.Field("owner_address", "bytes", repeated=False, required=True), + 2: protobuf.Field("to_address", "bytes", repeated=False, required=True), + 3: protobuf.Field("amount", "uint64", repeated=False, required=True), + } + + def __init__( + self, + *, + owner_address: "bytes", + to_address: "bytes", + amount: "int", + ) -> None: + self.owner_address = owner_address + self.to_address = to_address + self.amount = amount + + +class TronRawParameter(protobuf.MessageType): + MESSAGE_WIRE_TYPE = None + FIELDS = { + 1: protobuf.Field("type_url", "string", repeated=False, required=True), + 2: protobuf.Field("value", "bytes", repeated=False, required=True), + } + + def __init__( + self, + *, + type_url: "str", + value: "bytes", + ) -> None: + self.type_url = type_url + self.value = value + + class WebAuthnListResidentCredentials(protobuf.MessageType): MESSAGE_WIRE_TYPE = 800 diff --git a/python/src/trezorlib/tron.py b/python/src/trezorlib/tron.py index 3ad9813520a..defd9bf2769 100644 --- a/python/src/trezorlib/tron.py +++ b/python/src/trezorlib/tron.py @@ -1,14 +1,59 @@ -from typing import TYPE_CHECKING, Any +import io +from typing import TYPE_CHECKING, Any, Tuple -from . import messages +from . import messages, tools +from .protobuf import load_message if TYPE_CHECKING: from .tools import Address from .transport.session import Session + TronMessageType = messages.TronTransferContract + DEFAULT_BIP32_PATH = "m/44h/195h/0h/0/0" +def from_raw_data( + raw_data: bytes, +) -> Tuple[messages.TronSignTx, "TronMessageType"]: + raw_tx = load_message(io.BytesIO(raw_data), messages.TronRawTransaction) + + tx = messages.TronSignTx( + ref_block_bytes=raw_tx.ref_block_bytes, + ref_block_hash=raw_tx.ref_block_hash, + expiration=raw_tx.expiration, + timestamp=raw_tx.timestamp, + fee_limit=raw_tx.fee_limit, + data=raw_tx.data, + ) + + if len(raw_tx.contract) != 1: + raise ValueError("Only single contract transactions are supported.") + + contract_type = raw_tx.contract[0].type + if contract_type == messages.TronRawContractType.TransferContract: + raw_contract = load_message( + io.BytesIO(raw_tx.contract[0].parameter.value), + messages.TronRawTransferContract, + ) + contract = messages.TronTransferContract( + to_address=_encode_address(raw_contract.to_address), + owner_address=_encode_address(raw_contract.owner_address), + amount=raw_contract.amount, + ) + else: + raise ValueError(f"Unsupported contract type: {contract_type}") + + return tx, contract + + +def _encode_address(address: bytes) -> str: + return tools.b58check_encode(address) + + +# ====== Client functions ====== # + + def get_address(*args: Any, **kwargs: Any) -> str: return get_authenticated_address(*args, **kwargs).address @@ -25,3 +70,17 @@ def get_authenticated_address( ), expect=messages.TronAddress, ) + + +def sign_tx( + client: "TrezorClient", + tx: messages.TronSignTx, + contract: "TronMessageType", + address_n: "Address", +) -> messages.TronSignature: + tx.address_n = address_n + resp = client.call(tx) + messages.TronContractRequest.ensure_isinstance(resp) + resp = client.call(contract) + resp = messages.TronSignature.ensure_isinstance(resp) + return resp diff --git a/rust/trezor-client/src/messages/generated.rs b/rust/trezor-client/src/messages/generated.rs index 32ca32b17bf..fda0bf2cbce 100644 --- a/rust/trezor-client/src/messages/generated.rs +++ b/rust/trezor-client/src/messages/generated.rs @@ -311,6 +311,10 @@ trezor_message_impl! { trezor_message_impl! { TronGetAddress => MessageType_TronGetAddress, TronAddress => MessageType_TronAddress, + TronSignTx => MessageType_TronSignTx, + TronSignature => MessageType_TronSignature, + TronContractRequest => MessageType_TronContractRequest, + TronTransferContract => MessageType_TronTransferContract, } #[cfg(feature = "webauthn")] diff --git a/rust/trezor-client/src/protos/generated/messages.rs b/rust/trezor-client/src/protos/generated/messages.rs index c806fe6d1ff..4a067a8ee86 100644 --- a/rust/trezor-client/src/protos/generated/messages.rs +++ b/rust/trezor-client/src/protos/generated/messages.rs @@ -547,6 +547,14 @@ pub enum MessageType { MessageType_TronGetAddress = 2200, // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_TronAddress) MessageType_TronAddress = 2201, + // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_TronSignTx) + MessageType_TronSignTx = 2202, + // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_TronSignature) + MessageType_TronSignature = 2203, + // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_TronContractRequest) + MessageType_TronContractRequest = 2204, + // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_TronTransferContract) + MessageType_TronTransferContract = 2205, // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_BenchmarkListNames) MessageType_BenchmarkListNames = 9100, // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_BenchmarkNames) @@ -826,6 +834,10 @@ impl ::protobuf::Enum for MessageType { 2105 => ::std::option::Option::Some(MessageType::MessageType_EvoluDelegatedIdentityKey), 2200 => ::std::option::Option::Some(MessageType::MessageType_TronGetAddress), 2201 => ::std::option::Option::Some(MessageType::MessageType_TronAddress), + 2202 => ::std::option::Option::Some(MessageType::MessageType_TronSignTx), + 2203 => ::std::option::Option::Some(MessageType::MessageType_TronSignature), + 2204 => ::std::option::Option::Some(MessageType::MessageType_TronContractRequest), + 2205 => ::std::option::Option::Some(MessageType::MessageType_TronTransferContract), 9100 => ::std::option::Option::Some(MessageType::MessageType_BenchmarkListNames), 9101 => ::std::option::Option::Some(MessageType::MessageType_BenchmarkNames), 9102 => ::std::option::Option::Some(MessageType::MessageType_BenchmarkRun), @@ -1096,6 +1108,10 @@ impl ::protobuf::Enum for MessageType { "MessageType_EvoluDelegatedIdentityKey" => ::std::option::Option::Some(MessageType::MessageType_EvoluDelegatedIdentityKey), "MessageType_TronGetAddress" => ::std::option::Option::Some(MessageType::MessageType_TronGetAddress), "MessageType_TronAddress" => ::std::option::Option::Some(MessageType::MessageType_TronAddress), + "MessageType_TronSignTx" => ::std::option::Option::Some(MessageType::MessageType_TronSignTx), + "MessageType_TronSignature" => ::std::option::Option::Some(MessageType::MessageType_TronSignature), + "MessageType_TronContractRequest" => ::std::option::Option::Some(MessageType::MessageType_TronContractRequest), + "MessageType_TronTransferContract" => ::std::option::Option::Some(MessageType::MessageType_TronTransferContract), "MessageType_BenchmarkListNames" => ::std::option::Option::Some(MessageType::MessageType_BenchmarkListNames), "MessageType_BenchmarkNames" => ::std::option::Option::Some(MessageType::MessageType_BenchmarkNames), "MessageType_BenchmarkRun" => ::std::option::Option::Some(MessageType::MessageType_BenchmarkRun), @@ -1365,6 +1381,10 @@ impl ::protobuf::Enum for MessageType { MessageType::MessageType_EvoluDelegatedIdentityKey, MessageType::MessageType_TronGetAddress, MessageType::MessageType_TronAddress, + MessageType::MessageType_TronSignTx, + MessageType::MessageType_TronSignature, + MessageType::MessageType_TronContractRequest, + MessageType::MessageType_TronTransferContract, MessageType::MessageType_BenchmarkListNames, MessageType::MessageType_BenchmarkNames, MessageType::MessageType_BenchmarkRun, @@ -1640,10 +1660,14 @@ impl ::protobuf::EnumFull for MessageType { MessageType::MessageType_EvoluDelegatedIdentityKey => 257, MessageType::MessageType_TronGetAddress => 258, MessageType::MessageType_TronAddress => 259, - MessageType::MessageType_BenchmarkListNames => 260, - MessageType::MessageType_BenchmarkNames => 261, - MessageType::MessageType_BenchmarkRun => 262, - MessageType::MessageType_BenchmarkResult => 263, + MessageType::MessageType_TronSignTx => 260, + MessageType::MessageType_TronSignature => 261, + MessageType::MessageType_TronContractRequest => 262, + MessageType::MessageType_TronTransferContract => 263, + MessageType::MessageType_BenchmarkListNames => 264, + MessageType::MessageType_BenchmarkNames => 265, + MessageType::MessageType_BenchmarkRun => 266, + MessageType::MessageType_BenchmarkResult => 267, }; Self::enum_descriptor().value_by_index(index) } @@ -1662,7 +1686,7 @@ impl MessageType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\roptions.proto*\xa7\\\ + \n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\roptions.proto*\xc9]\ \n\x0bMessageType\x12(\n\x16MessageType_Initialize\x10\0\x1a\x0c\x80\xa6\ \x1d\x01\xb0\xb5\x18\x01\x90\xb5\x18\x01\x12\x1e\n\x10MessageType_Ping\ \x10\x01\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12%\n\x13MessageType_S\ @@ -1960,17 +1984,21 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x1d\x01\x90\xb5\x18\x01\x124\n%MessageType_EvoluDelegatedIdentityKey\ \x10\xb9\x10\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12%\n\x1aMessageTy\ pe_TronGetAddress\x10\x98\x11\x1a\x04\x90\xb5\x18\x01\x12\"\n\x17Message\ - Type_TronAddress\x10\x99\x11\x1a\x04\x98\xb5\x18\x01\x12)\n\x1eMessageTy\ - pe_BenchmarkListNames\x10\x8cG\x1a\x04\x80\xa6\x1d\x01\x12%\n\x1aMessage\ - Type_BenchmarkNames\x10\x8dG\x1a\x04\x80\xa6\x1d\x01\x12#\n\x18MessageTy\ - pe_BenchmarkRun\x10\x8eG\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1bMessageType_B\ - enchmarkResult\x10\x8fG\x1a\x04\x80\xa6\x1d\x01\x1a\x08\xc8\xf3\x18\x01\ - \xd0\xf3\x18\x01\"\x04\x08Z\x10\\\"\x04\x08G\x10J\"\x04\x08r\x10z\"\x05\ - \x08{\x10\x95\x01\"\x06\x08\xdb\x01\x10\xdb\x01\"\x06\x08\xe0\x01\x10\ - \xe0\x01\"\x06\x08\xac\x02\x10\xb0\x02\"\x06\x08\xb5\x02\x10\xb8\x02\"\ - \x06\x08\xbc\x05\x10\xc5\x05\"\x06\x08\xe9\x07\x10\xf7\x07\"\x06\x08\xfa\ - \x07\x10\xcb\x08B8\n#com.satoshilabs.trezor.lib.protobufB\rTrezorMessage\ - \x80\xa6\x1d\x01\ + Type_TronAddress\x10\x99\x11\x1a\x04\x98\xb5\x18\x01\x12!\n\x16MessageTy\ + pe_TronSignTx\x10\x9a\x11\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_\ + TronSignature\x10\x9b\x11\x1a\x04\x98\xb5\x18\x01\x12*\n\x1fMessageType_\ + TronContractRequest\x10\x9c\x11\x1a\x04\x98\xb5\x18\x01\x12+\n\x20Messag\ + eType_TronTransferContract\x10\x9d\x11\x1a\x04\x90\xb5\x18\x01\x12)\n\ + \x1eMessageType_BenchmarkListNames\x10\x8cG\x1a\x04\x80\xa6\x1d\x01\x12%\ + \n\x1aMessageType_BenchmarkNames\x10\x8dG\x1a\x04\x80\xa6\x1d\x01\x12#\n\ + \x18MessageType_BenchmarkRun\x10\x8eG\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1b\ + MessageType_BenchmarkResult\x10\x8fG\x1a\x04\x80\xa6\x1d\x01\x1a\x08\xc8\ + \xf3\x18\x01\xd0\xf3\x18\x01\"\x04\x08Z\x10\\\"\x04\x08G\x10J\"\x04\x08r\ + \x10z\"\x05\x08{\x10\x95\x01\"\x06\x08\xdb\x01\x10\xdb\x01\"\x06\x08\xe0\ + \x01\x10\xe0\x01\"\x06\x08\xac\x02\x10\xb0\x02\"\x06\x08\xb5\x02\x10\xb8\ + \x02\"\x06\x08\xbc\x05\x10\xc5\x05\"\x06\x08\xe9\x07\x10\xf7\x07\"\x06\ + \x08\xfa\x07\x10\xcb\x08B8\n#com.satoshilabs.trezor.lib.protobufB\rTrezo\ + rMessage\x80\xa6\x1d\x01\ "; /// `FileDescriptorProto` object which was a source for this generated file diff --git a/rust/trezor-client/src/protos/generated/messages_management.rs b/rust/trezor-client/src/protos/generated/messages_management.rs index 5152df54164..685380cc399 100644 --- a/rust/trezor-client/src/protos/generated/messages_management.rs +++ b/rust/trezor-client/src/protos/generated/messages_management.rs @@ -2978,6 +2978,8 @@ pub mod features { Capability_BLE = 22, // @@protoc_insertion_point(enum_value:hw.trezor.messages.management.Features.Capability.Capability_NFC) Capability_NFC = 23, + // @@protoc_insertion_point(enum_value:hw.trezor.messages.management.Features.Capability.Capability_Tron) + Capability_Tron = 24, } impl ::protobuf::Enum for Capability { @@ -3012,6 +3014,7 @@ pub mod features { 21 => ::std::option::Option::Some(Capability::Capability_Haptic), 22 => ::std::option::Option::Some(Capability::Capability_BLE), 23 => ::std::option::Option::Some(Capability::Capability_NFC), + 24 => ::std::option::Option::Some(Capability::Capability_Tron), _ => ::std::option::Option::None } } @@ -3041,6 +3044,7 @@ pub mod features { "Capability_Haptic" => ::std::option::Option::Some(Capability::Capability_Haptic), "Capability_BLE" => ::std::option::Option::Some(Capability::Capability_BLE), "Capability_NFC" => ::std::option::Option::Some(Capability::Capability_NFC), + "Capability_Tron" => ::std::option::Option::Some(Capability::Capability_Tron), _ => ::std::option::Option::None } } @@ -3069,6 +3073,7 @@ pub mod features { Capability::Capability_Haptic, Capability::Capability_BLE, Capability::Capability_NFC, + Capability::Capability_Tron, ]; } @@ -3103,6 +3108,7 @@ pub mod features { Capability::Capability_Haptic => 20, Capability::Capability_BLE => 21, Capability::Capability_NFC => 22, + Capability::Capability_Tron => 23, }; Self::enum_descriptor().value_by_index(index) } @@ -12208,7 +12214,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \roptions.proto\"\x80\x01\n\nInitialize\x12\x1d\n\nsession_id\x18\x01\ \x20\x01(\x0cR\tsessionId\x12,\n\x10_skip_passphrase\x18\x02\x20\x01(\ \x08R\x0eSkipPassphraseB\x02\x18\x01\x12%\n\x0ederive_cardano\x18\x03\ - \x20\x01(\x08R\rderiveCardano\"\r\n\x0bGetFeatures\"\x9d\x1a\n\x08Featur\ + \x20\x01(\x08R\rderiveCardano\"\r\n\x0bGetFeatures\"\xb2\x1a\n\x08Featur\ es\x12\x16\n\x06vendor\x18\x01\x20\x01(\tR\x06vendor\x12#\n\rmajor_versi\ on\x18\x02\x20\x02(\rR\x0cmajorVersion\x12#\n\rminor_version\x18\x03\x20\ \x02(\rR\x0cminorVersion\x12#\n\rpatch_version\x18\x04\x20\x02(\rR\x0cpa\ @@ -12267,7 +12273,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ lessConnected\"C\n\x12BackupAvailability\x12\x10\n\x0cNotAvailable\x10\0\ \x12\x0c\n\x08Required\x10\x01\x12\r\n\tAvailable\x10\x02\"7\n\x0eRecove\ ryStatus\x12\x0b\n\x07Nothing\x10\0\x12\x0c\n\x08Recovery\x10\x01\x12\n\ - \n\x06Backup\x10\x02\"\xf6\x04\n\nCapability\x12\x1c\n\x12Capability_Bit\ + \n\x06Backup\x10\x02\"\x8b\x05\n\nCapability\x12\x1c\n\x12Capability_Bit\ coin\x10\x01\x1a\x04\x80\xa6\x1d\x01\x12\x1b\n\x17Capability_Bitcoin_lik\ e\x10\x02\x12\x16\n\x12Capability_Binance\x10\x03\x12\x16\n\x12Capabilit\ y_Cardano\x10\x04\x12\x1b\n\x11Capability_Crypto\x10\x05\x1a\x04\x80\xa6\ @@ -12283,120 +12289,121 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x04\x80\xa6\x1d\x01\x12\x1f\n\x15Capability_Brightness\x10\x14\x1a\x04\ \x80\xa6\x1d\x01\x12\x1b\n\x11Capability_Haptic\x10\x15\x1a\x04\x80\xa6\ \x1d\x01\x12\x18\n\x0eCapability_BLE\x10\x16\x1a\x04\x80\xa6\x1d\x01\x12\ - \x18\n\x0eCapability_NFC\x10\x17\x1a\x04\x80\xa6\x1d\x01\x1a\x04\xc8\xf3\ - \x18\x01\"\x0c\n\nLockDevice\"&\n\x07SetBusy\x12\x1b\n\texpiry_ms\x18\ - \x01\x20\x01(\rR\x08expiryMs\"\x0c\n\nEndSession\"\xdd\x05\n\rApplySetti\ - ngs\x12\x1e\n\x08language\x18\x01\x20\x01(\tR\x08languageB\x02\x18\x01\ - \x12\x14\n\x05label\x18\x02\x20\x01(\tR\x05label\x12%\n\x0euse_passphras\ - e\x18\x03\x20\x01(\x08R\rusePassphrase\x12\x1e\n\nhomescreen\x18\x04\x20\ - \x01(\x0cR\nhomescreen\x120\n\x12_passphrase_source\x18\x05\x20\x01(\rR\ - \x10PassphraseSourceB\x02\x18\x01\x12+\n\x12auto_lock_delay_ms\x18\x06\ - \x20\x01(\rR\x0fautoLockDelayMs\x12Y\n\x10display_rotation\x18\x07\x20\ - \x01(\x0e2..hw.trezor.messages.management.DisplayRotationR\x0fdisplayRot\ - ation\x12=\n\x1bpassphrase_always_on_device\x18\x08\x20\x01(\x08R\x18pas\ - sphraseAlwaysOnDevice\x12T\n\rsafety_checks\x18\t\x20\x01(\x0e2/.hw.trez\ - or.messages.management.SafetyCheckLevelR\x0csafetyChecks\x123\n\x15exper\ - imental_features\x18\n\x20\x01(\x08R\x14experimentalFeatures\x129\n\x19h\ - ide_passphrase_from_host\x18\x0b\x20\x01(\x08R\x16hidePassphraseFromHost\ - \x12'\n\x0fhaptic_feedback\x18\r\x20\x01(\x08R\x0ehapticFeedback\x12+\n\ - \x11homescreen_length\x18\x0e\x20\x01(\rR\x10homescreenLength\x12:\n\x1a\ - auto_lock_delay_battery_ms\x18\x0f\x20\x01(\rR\x16autoLockDelayBatteryMs\ - \"T\n\x0eChangeLanguage\x12\x1f\n\x0bdata_length\x18\x01\x20\x02(\rR\nda\ - taLength\x12!\n\x0cshow_display\x18\x02\x20\x01(\x08R\x0bshowDisplay\"T\ - \n\x10DataChunkRequest\x12\x1f\n\x0bdata_length\x18\x01\x20\x02(\rR\ndat\ - aLength\x12\x1f\n\x0bdata_offset\x18\x02\x20\x02(\rR\ndataOffset\"-\n\ - \x0cDataChunkAck\x12\x1d\n\ndata_chunk\x18\x01\x20\x02(\x0cR\tdataChunk\ - \"\"\n\nApplyFlags\x12\x14\n\x05flags\x18\x01\x20\x02(\rR\x05flags\"#\n\ - \tChangePin\x12\x16\n\x06remove\x18\x01\x20\x01(\x08R\x06remove\"(\n\x0e\ - ChangeWipeCode\x12\x16\n\x06remove\x18\x01\x20\x01(\x08R\x06remove\"\xaa\ - \x01\n\tSdProtect\x12]\n\toperation\x18\x01\x20\x02(\x0e2?.hw.trezor.mes\ - sages.management.SdProtect.SdProtectOperationTypeR\toperation\">\n\x16Sd\ - ProtectOperationType\x12\x0b\n\x07DISABLE\x10\0\x12\n\n\x06ENABLE\x10\ - \x01\x12\x0b\n\x07REFRESH\x10\x02\"O\n\x04Ping\x12\x1a\n\x07message\x18\ - \x01\x20\x01(\t:\0R\x07message\x12+\n\x11button_protection\x18\x02\x20\ - \x01(\x08R\x10buttonProtection\"\x08\n\x06Cancel\"\x20\n\nGetEntropy\x12\ - \x12\n\x04size\x18\x01\x20\x02(\rR\x04size\"#\n\x07Entropy\x12\x18\n\x07\ - entropy\x18\x01\x20\x02(\x0cR\x07entropy\"/\n\x0fGetFirmwareHash\x12\x1c\ - \n\tchallenge\x18\x01\x20\x01(\x0cR\tchallenge\"\"\n\x0cFirmwareHash\x12\ - \x12\n\x04hash\x18\x01\x20\x02(\x0cR\x04hash\"2\n\x12AuthenticateDevice\ - \x12\x1c\n\tchallenge\x18\x01\x20\x02(\x0cR\tchallenge\"\xcb\x01\n\x11Au\ - thenticityProof\x12/\n\x13optiga_certificates\x18\x01\x20\x03(\x0cR\x12o\ - ptigaCertificates\x12)\n\x10optiga_signature\x18\x02\x20\x02(\x0cR\x0fop\ - tigaSignature\x12/\n\x13tropic_certificates\x18\x03\x20\x03(\x0cR\x12tro\ - picCertificates\x12)\n\x10tropic_signature\x18\x04\x20\x01(\x0cR\x0ftrop\ - icSignature\"\x0c\n\nWipeDevice\"\xad\x02\n\nLoadDevice\x12\x1c\n\tmnemo\ - nics\x18\x01\x20\x03(\tR\tmnemonics\x12\x10\n\x03pin\x18\x03\x20\x01(\tR\ - \x03pin\x123\n\x15passphrase_protection\x18\x04\x20\x01(\x08R\x14passphr\ - aseProtection\x12\x1e\n\x08language\x18\x05\x20\x01(\tR\x08languageB\x02\ - \x18\x01\x12\x14\n\x05label\x18\x06\x20\x01(\tR\x05label\x12#\n\rskip_ch\ - ecksum\x18\x07\x20\x01(\x08R\x0cskipChecksum\x12\x1f\n\x0bu2f_counter\ - \x18\x08\x20\x01(\rR\nu2fCounter\x12!\n\x0cneeds_backup\x18\t\x20\x01(\ - \x08R\x0bneedsBackup\x12\x1b\n\tno_backup\x18\n\x20\x01(\x08R\x08noBacku\ - p\"\x9d\x03\n\x0bResetDevice\x12\x1f\n\x08strength\x18\x02\x20\x01(\r:\ - \x03256R\x08strength\x123\n\x15passphrase_protection\x18\x03\x20\x01(\ - \x08R\x14passphraseProtection\x12%\n\x0epin_protection\x18\x04\x20\x01(\ - \x08R\rpinProtection\x12\x1e\n\x08language\x18\x05\x20\x01(\tR\x08langua\ - geB\x02\x18\x01\x12\x14\n\x05label\x18\x06\x20\x01(\tR\x05label\x12\x1f\ - \n\x0bu2f_counter\x18\x07\x20\x01(\rR\nu2fCounter\x12\x1f\n\x0bskip_back\ - up\x18\x08\x20\x01(\x08R\nskipBackup\x12\x1b\n\tno_backup\x18\t\x20\x01(\ - \x08R\x08noBackup\x12Q\n\x0bbackup_type\x18\n\x20\x01(\x0e2).hw.trezor.m\ - essages.management.BackupType:\x05Bip39R\nbackupType\x12#\n\rentropy_che\ - ck\x18\x0b\x20\x01(\x08R\x0centropyCheckJ\x04\x08\x01\x10\x02\"\xe5\x01\ - \n\x0cBackupDevice\x12'\n\x0fgroup_threshold\x18\x01\x20\x01(\rR\x0egrou\ - pThreshold\x12O\n\x06groups\x18\x02\x20\x03(\x0b27.hw.trezor.messages.ma\ - nagement.BackupDevice.Slip39GroupR\x06groups\x1a[\n\x0bSlip39Group\x12)\ - \n\x10member_threshold\x18\x01\x20\x02(\rR\x0fmemberThreshold\x12!\n\x0c\ - member_count\x18\x02\x20\x02(\rR\x0bmemberCount\"b\n\x0eEntropyRequest\ - \x12-\n\x12entropy_commitment\x18\x01\x20\x01(\x0cR\x11entropyCommitment\ - \x12!\n\x0cprev_entropy\x18\x02\x20\x01(\x0cR\x0bprevEntropy\"&\n\nEntro\ - pyAck\x12\x18\n\x07entropy\x18\x01\x20\x02(\x0cR\x07entropy\"\x13\n\x11E\ - ntropyCheckReady\"5\n\x14EntropyCheckContinue\x12\x1d\n\x06finish\x18\ - \x01\x20\x01(\x08:\x05falseR\x06finish\"\x8d\x04\n\x0eRecoveryDevice\x12\ - \x1d\n\nword_count\x18\x01\x20\x01(\rR\twordCount\x123\n\x15passphrase_p\ - rotection\x18\x02\x20\x01(\x08R\x14passphraseProtection\x12%\n\x0epin_pr\ - otection\x18\x03\x20\x01(\x08R\rpinProtection\x12\x1e\n\x08language\x18\ - \x04\x20\x01(\tR\x08languageB\x02\x18\x01\x12\x14\n\x05label\x18\x05\x20\ - \x01(\tR\x05label\x12)\n\x10enforce_wordlist\x18\x06\x20\x01(\x08R\x0fen\ - forceWordlist\x12j\n\x0cinput_method\x18\x08\x20\x01(\x0e2G.hw.trezor.me\ - ssages.management.RecoveryDevice.RecoveryDeviceInputMethodR\x0binputMeth\ - od\x12\x1f\n\x0bu2f_counter\x18\t\x20\x01(\rR\nu2fCounter\x12O\n\x04type\ - \x18\n\x20\x01(\x0e2+.hw.trezor.messages.management.RecoveryType:\x0eNor\ - malRecoveryR\x04type\";\n\x19RecoveryDeviceInputMethod\x12\x12\n\x0eScra\ - mbledWords\x10\0\x12\n\n\x06Matrix\x10\x01J\x04\x08\x07\x10\x08\"\xc5\ - \x01\n\x0bWordRequest\x12N\n\x04type\x18\x01\x20\x02(\x0e2:.hw.trezor.me\ - ssages.management.WordRequest.WordRequestTypeR\x04type\"f\n\x0fWordReque\ - stType\x12\x19\n\x15WordRequestType_Plain\x10\0\x12\x1b\n\x17WordRequest\ - Type_Matrix9\x10\x01\x12\x1b\n\x17WordRequestType_Matrix6\x10\x02\"\x1d\ - \n\x07WordAck\x12\x12\n\x04word\x18\x01\x20\x02(\tR\x04word\"0\n\rSetU2F\ - Counter\x12\x1f\n\x0bu2f_counter\x18\x01\x20\x02(\rR\nu2fCounter\"\x13\n\ - \x11GetNextU2FCounter\"1\n\x0eNextU2FCounter\x12\x1f\n\x0bu2f_counter\ - \x18\x01\x20\x02(\rR\nu2fCounter\"\x11\n\x0fDoPreauthorized\"\x16\n\x14P\ - reauthorizedRequest\"\x15\n\x13CancelAuthorization\"\x9a\x02\n\x12Reboot\ - ToBootloader\x12o\n\x0cboot_command\x18\x01\x20\x01(\x0e2=.hw.trezor.mes\ - sages.management.RebootToBootloader.BootCommand:\rSTOP_AND_WAITR\x0bboot\ - Command\x12'\n\x0ffirmware_header\x18\x02\x20\x01(\x0cR\x0efirmwareHeade\ - r\x123\n\x14language_data_length\x18\x03\x20\x01(\r:\x010R\x12languageDa\ - taLength\"5\n\x0bBootCommand\x12\x11\n\rSTOP_AND_WAIT\x10\0\x12\x13\n\ - \x0fINSTALL_UPGRADE\x10\x01\"\x10\n\x08GetNonce:\x04\x88\xb2\x19\x01\"#\ - \n\x05Nonce\x12\x14\n\x05nonce\x18\x01\x20\x02(\x0cR\x05nonce:\x04\x88\ - \xb2\x19\x01\";\n\nUnlockPath\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\ - \x08addressN\x12\x10\n\x03mac\x18\x02\x20\x01(\x0cR\x03mac\"'\n\x13Unloc\ - kedPathRequest\x12\x10\n\x03mac\x18\x01\x20\x02(\x0cR\x03mac\"\x14\n\x12\ - ShowDeviceTutorial\"\x12\n\x10UnlockBootloader\"%\n\rSetBrightness\x12\ - \x14\n\x05value\x18\x01\x20\x01(\rR\x05value\"\x11\n\x0fGetSerialNumber\ - \"3\n\x0cSerialNumber\x12#\n\rserial_number\x18\x01\x20\x02(\tR\x0cseria\ - lNumber*\x99\x01\n\nBackupType\x12\t\n\x05Bip39\x10\0\x12\x10\n\x0cSlip3\ - 9_Basic\x10\x01\x12\x13\n\x0fSlip39_Advanced\x10\x02\x12\x1c\n\x18Slip39\ - _Single_Extendable\x10\x03\x12\x1b\n\x17Slip39_Basic_Extendable\x10\x04\ - \x12\x1e\n\x1aSlip39_Advanced_Extendable\x10\x05*G\n\x10SafetyCheckLevel\ - \x12\n\n\x06Strict\x10\0\x12\x10\n\x0cPromptAlways\x10\x01\x12\x15\n\x11\ - PromptTemporarily\x10\x02*=\n\x0fDisplayRotation\x12\t\n\x05North\x10\0\ - \x12\x08\n\x04East\x10Z\x12\n\n\x05South\x10\xb4\x01\x12\t\n\x04West\x10\ - \x8e\x02*0\n\x10HomescreenFormat\x12\x08\n\x04Toif\x10\x01\x12\x08\n\x04\ - Jpeg\x10\x02\x12\x08\n\x04ToiG\x10\x03*H\n\x0cRecoveryType\x12\x12\n\x0e\ - NormalRecovery\x10\0\x12\n\n\x06DryRun\x10\x01\x12\x18\n\x14UnlockRepeat\ - edBackup\x10\x02BB\n#com.satoshilabs.trezor.lib.protobufB\x17TrezorMessa\ - geManagement\x80\xa6\x1d\x01\ + \x18\n\x0eCapability_NFC\x10\x17\x1a\x04\x80\xa6\x1d\x01\x12\x13\n\x0fCa\ + pability_Tron\x10\x18\x1a\x04\xc8\xf3\x18\x01\"\x0c\n\nLockDevice\"&\n\ + \x07SetBusy\x12\x1b\n\texpiry_ms\x18\x01\x20\x01(\rR\x08expiryMs\"\x0c\n\ + \nEndSession\"\xdd\x05\n\rApplySettings\x12\x1e\n\x08language\x18\x01\ + \x20\x01(\tR\x08languageB\x02\x18\x01\x12\x14\n\x05label\x18\x02\x20\x01\ + (\tR\x05label\x12%\n\x0euse_passphrase\x18\x03\x20\x01(\x08R\rusePassphr\ + ase\x12\x1e\n\nhomescreen\x18\x04\x20\x01(\x0cR\nhomescreen\x120\n\x12_p\ + assphrase_source\x18\x05\x20\x01(\rR\x10PassphraseSourceB\x02\x18\x01\ + \x12+\n\x12auto_lock_delay_ms\x18\x06\x20\x01(\rR\x0fautoLockDelayMs\x12\ + Y\n\x10display_rotation\x18\x07\x20\x01(\x0e2..hw.trezor.messages.manage\ + ment.DisplayRotationR\x0fdisplayRotation\x12=\n\x1bpassphrase_always_on_\ + device\x18\x08\x20\x01(\x08R\x18passphraseAlwaysOnDevice\x12T\n\rsafety_\ + checks\x18\t\x20\x01(\x0e2/.hw.trezor.messages.management.SafetyCheckLev\ + elR\x0csafetyChecks\x123\n\x15experimental_features\x18\n\x20\x01(\x08R\ + \x14experimentalFeatures\x129\n\x19hide_passphrase_from_host\x18\x0b\x20\ + \x01(\x08R\x16hidePassphraseFromHost\x12'\n\x0fhaptic_feedback\x18\r\x20\ + \x01(\x08R\x0ehapticFeedback\x12+\n\x11homescreen_length\x18\x0e\x20\x01\ + (\rR\x10homescreenLength\x12:\n\x1aauto_lock_delay_battery_ms\x18\x0f\ + \x20\x01(\rR\x16autoLockDelayBatteryMs\"T\n\x0eChangeLanguage\x12\x1f\n\ + \x0bdata_length\x18\x01\x20\x02(\rR\ndataLength\x12!\n\x0cshow_display\ + \x18\x02\x20\x01(\x08R\x0bshowDisplay\"T\n\x10DataChunkRequest\x12\x1f\n\ + \x0bdata_length\x18\x01\x20\x02(\rR\ndataLength\x12\x1f\n\x0bdata_offset\ + \x18\x02\x20\x02(\rR\ndataOffset\"-\n\x0cDataChunkAck\x12\x1d\n\ndata_ch\ + unk\x18\x01\x20\x02(\x0cR\tdataChunk\"\"\n\nApplyFlags\x12\x14\n\x05flag\ + s\x18\x01\x20\x02(\rR\x05flags\"#\n\tChangePin\x12\x16\n\x06remove\x18\ + \x01\x20\x01(\x08R\x06remove\"(\n\x0eChangeWipeCode\x12\x16\n\x06remove\ + \x18\x01\x20\x01(\x08R\x06remove\"\xaa\x01\n\tSdProtect\x12]\n\toperatio\ + n\x18\x01\x20\x02(\x0e2?.hw.trezor.messages.management.SdProtect.SdProte\ + ctOperationTypeR\toperation\">\n\x16SdProtectOperationType\x12\x0b\n\x07\ + DISABLE\x10\0\x12\n\n\x06ENABLE\x10\x01\x12\x0b\n\x07REFRESH\x10\x02\"O\ + \n\x04Ping\x12\x1a\n\x07message\x18\x01\x20\x01(\t:\0R\x07message\x12+\n\ + \x11button_protection\x18\x02\x20\x01(\x08R\x10buttonProtection\"\x08\n\ + \x06Cancel\"\x20\n\nGetEntropy\x12\x12\n\x04size\x18\x01\x20\x02(\rR\x04\ + size\"#\n\x07Entropy\x12\x18\n\x07entropy\x18\x01\x20\x02(\x0cR\x07entro\ + py\"/\n\x0fGetFirmwareHash\x12\x1c\n\tchallenge\x18\x01\x20\x01(\x0cR\tc\ + hallenge\"\"\n\x0cFirmwareHash\x12\x12\n\x04hash\x18\x01\x20\x02(\x0cR\ + \x04hash\"2\n\x12AuthenticateDevice\x12\x1c\n\tchallenge\x18\x01\x20\x02\ + (\x0cR\tchallenge\"\xcb\x01\n\x11AuthenticityProof\x12/\n\x13optiga_cert\ + ificates\x18\x01\x20\x03(\x0cR\x12optigaCertificates\x12)\n\x10optiga_si\ + gnature\x18\x02\x20\x02(\x0cR\x0foptigaSignature\x12/\n\x13tropic_certif\ + icates\x18\x03\x20\x03(\x0cR\x12tropicCertificates\x12)\n\x10tropic_sign\ + ature\x18\x04\x20\x01(\x0cR\x0ftropicSignature\"\x0c\n\nWipeDevice\"\xad\ + \x02\n\nLoadDevice\x12\x1c\n\tmnemonics\x18\x01\x20\x03(\tR\tmnemonics\ + \x12\x10\n\x03pin\x18\x03\x20\x01(\tR\x03pin\x123\n\x15passphrase_protec\ + tion\x18\x04\x20\x01(\x08R\x14passphraseProtection\x12\x1e\n\x08language\ + \x18\x05\x20\x01(\tR\x08languageB\x02\x18\x01\x12\x14\n\x05label\x18\x06\ + \x20\x01(\tR\x05label\x12#\n\rskip_checksum\x18\x07\x20\x01(\x08R\x0cski\ + pChecksum\x12\x1f\n\x0bu2f_counter\x18\x08\x20\x01(\rR\nu2fCounter\x12!\ + \n\x0cneeds_backup\x18\t\x20\x01(\x08R\x0bneedsBackup\x12\x1b\n\tno_back\ + up\x18\n\x20\x01(\x08R\x08noBackup\"\x9d\x03\n\x0bResetDevice\x12\x1f\n\ + \x08strength\x18\x02\x20\x01(\r:\x03256R\x08strength\x123\n\x15passphras\ + e_protection\x18\x03\x20\x01(\x08R\x14passphraseProtection\x12%\n\x0epin\ + _protection\x18\x04\x20\x01(\x08R\rpinProtection\x12\x1e\n\x08language\ + \x18\x05\x20\x01(\tR\x08languageB\x02\x18\x01\x12\x14\n\x05label\x18\x06\ + \x20\x01(\tR\x05label\x12\x1f\n\x0bu2f_counter\x18\x07\x20\x01(\rR\nu2fC\ + ounter\x12\x1f\n\x0bskip_backup\x18\x08\x20\x01(\x08R\nskipBackup\x12\ + \x1b\n\tno_backup\x18\t\x20\x01(\x08R\x08noBackup\x12Q\n\x0bbackup_type\ + \x18\n\x20\x01(\x0e2).hw.trezor.messages.management.BackupType:\x05Bip39\ + R\nbackupType\x12#\n\rentropy_check\x18\x0b\x20\x01(\x08R\x0centropyChec\ + kJ\x04\x08\x01\x10\x02\"\xe5\x01\n\x0cBackupDevice\x12'\n\x0fgroup_thres\ + hold\x18\x01\x20\x01(\rR\x0egroupThreshold\x12O\n\x06groups\x18\x02\x20\ + \x03(\x0b27.hw.trezor.messages.management.BackupDevice.Slip39GroupR\x06g\ + roups\x1a[\n\x0bSlip39Group\x12)\n\x10member_threshold\x18\x01\x20\x02(\ + \rR\x0fmemberThreshold\x12!\n\x0cmember_count\x18\x02\x20\x02(\rR\x0bmem\ + berCount\"b\n\x0eEntropyRequest\x12-\n\x12entropy_commitment\x18\x01\x20\ + \x01(\x0cR\x11entropyCommitment\x12!\n\x0cprev_entropy\x18\x02\x20\x01(\ + \x0cR\x0bprevEntropy\"&\n\nEntropyAck\x12\x18\n\x07entropy\x18\x01\x20\ + \x02(\x0cR\x07entropy\"\x13\n\x11EntropyCheckReady\"5\n\x14EntropyCheckC\ + ontinue\x12\x1d\n\x06finish\x18\x01\x20\x01(\x08:\x05falseR\x06finish\"\ + \x8d\x04\n\x0eRecoveryDevice\x12\x1d\n\nword_count\x18\x01\x20\x01(\rR\t\ + wordCount\x123\n\x15passphrase_protection\x18\x02\x20\x01(\x08R\x14passp\ + hraseProtection\x12%\n\x0epin_protection\x18\x03\x20\x01(\x08R\rpinProte\ + ction\x12\x1e\n\x08language\x18\x04\x20\x01(\tR\x08languageB\x02\x18\x01\ + \x12\x14\n\x05label\x18\x05\x20\x01(\tR\x05label\x12)\n\x10enforce_wordl\ + ist\x18\x06\x20\x01(\x08R\x0fenforceWordlist\x12j\n\x0cinput_method\x18\ + \x08\x20\x01(\x0e2G.hw.trezor.messages.management.RecoveryDevice.Recover\ + yDeviceInputMethodR\x0binputMethod\x12\x1f\n\x0bu2f_counter\x18\t\x20\ + \x01(\rR\nu2fCounter\x12O\n\x04type\x18\n\x20\x01(\x0e2+.hw.trezor.messa\ + ges.management.RecoveryType:\x0eNormalRecoveryR\x04type\";\n\x19Recovery\ + DeviceInputMethod\x12\x12\n\x0eScrambledWords\x10\0\x12\n\n\x06Matrix\ + \x10\x01J\x04\x08\x07\x10\x08\"\xc5\x01\n\x0bWordRequest\x12N\n\x04type\ + \x18\x01\x20\x02(\x0e2:.hw.trezor.messages.management.WordRequest.WordRe\ + questTypeR\x04type\"f\n\x0fWordRequestType\x12\x19\n\x15WordRequestType_\ + Plain\x10\0\x12\x1b\n\x17WordRequestType_Matrix9\x10\x01\x12\x1b\n\x17Wo\ + rdRequestType_Matrix6\x10\x02\"\x1d\n\x07WordAck\x12\x12\n\x04word\x18\ + \x01\x20\x02(\tR\x04word\"0\n\rSetU2FCounter\x12\x1f\n\x0bu2f_counter\ + \x18\x01\x20\x02(\rR\nu2fCounter\"\x13\n\x11GetNextU2FCounter\"1\n\x0eNe\ + xtU2FCounter\x12\x1f\n\x0bu2f_counter\x18\x01\x20\x02(\rR\nu2fCounter\"\ + \x11\n\x0fDoPreauthorized\"\x16\n\x14PreauthorizedRequest\"\x15\n\x13Can\ + celAuthorization\"\x9a\x02\n\x12RebootToBootloader\x12o\n\x0cboot_comman\ + d\x18\x01\x20\x01(\x0e2=.hw.trezor.messages.management.RebootToBootloade\ + r.BootCommand:\rSTOP_AND_WAITR\x0bbootCommand\x12'\n\x0ffirmware_header\ + \x18\x02\x20\x01(\x0cR\x0efirmwareHeader\x123\n\x14language_data_length\ + \x18\x03\x20\x01(\r:\x010R\x12languageDataLength\"5\n\x0bBootCommand\x12\ + \x11\n\rSTOP_AND_WAIT\x10\0\x12\x13\n\x0fINSTALL_UPGRADE\x10\x01\"\x10\n\ + \x08GetNonce:\x04\x88\xb2\x19\x01\"#\n\x05Nonce\x12\x14\n\x05nonce\x18\ + \x01\x20\x02(\x0cR\x05nonce:\x04\x88\xb2\x19\x01\";\n\nUnlockPath\x12\ + \x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x10\n\x03mac\x18\ + \x02\x20\x01(\x0cR\x03mac\"'\n\x13UnlockedPathRequest\x12\x10\n\x03mac\ + \x18\x01\x20\x02(\x0cR\x03mac\"\x14\n\x12ShowDeviceTutorial\"\x12\n\x10U\ + nlockBootloader\"%\n\rSetBrightness\x12\x14\n\x05value\x18\x01\x20\x01(\ + \rR\x05value\"\x11\n\x0fGetSerialNumber\"3\n\x0cSerialNumber\x12#\n\rser\ + ial_number\x18\x01\x20\x02(\tR\x0cserialNumber*\x99\x01\n\nBackupType\ + \x12\t\n\x05Bip39\x10\0\x12\x10\n\x0cSlip39_Basic\x10\x01\x12\x13\n\x0fS\ + lip39_Advanced\x10\x02\x12\x1c\n\x18Slip39_Single_Extendable\x10\x03\x12\ + \x1b\n\x17Slip39_Basic_Extendable\x10\x04\x12\x1e\n\x1aSlip39_Advanced_E\ + xtendable\x10\x05*G\n\x10SafetyCheckLevel\x12\n\n\x06Strict\x10\0\x12\ + \x10\n\x0cPromptAlways\x10\x01\x12\x15\n\x11PromptTemporarily\x10\x02*=\ + \n\x0fDisplayRotation\x12\t\n\x05North\x10\0\x12\x08\n\x04East\x10Z\x12\ + \n\n\x05South\x10\xb4\x01\x12\t\n\x04West\x10\x8e\x02*0\n\x10HomescreenF\ + ormat\x12\x08\n\x04Toif\x10\x01\x12\x08\n\x04Jpeg\x10\x02\x12\x08\n\x04T\ + oiG\x10\x03*H\n\x0cRecoveryType\x12\x12\n\x0eNormalRecovery\x10\0\x12\n\ + \n\x06DryRun\x10\x01\x12\x18\n\x14UnlockRepeatedBackup\x10\x02BB\n#com.s\ + atoshilabs.trezor.lib.protobufB\x17TrezorMessageManagement\x80\xa6\x1d\ + \x01\ "; /// `FileDescriptorProto` object which was a source for this generated file diff --git a/rust/trezor-client/src/protos/generated/messages_tron.rs b/rust/trezor-client/src/protos/generated/messages_tron.rs index 975ec011ece..1fbe0d49d59 100644 --- a/rust/trezor-client/src/protos/generated/messages_tron.rs +++ b/rust/trezor-client/src/protos/generated/messages_tron.rs @@ -438,13 +438,2101 @@ impl ::protobuf::reflect::ProtobufValue for TronAddress { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +// @@protoc_insertion_point(message:hw.trezor.messages.tron.TronSignTx) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct TronSignTx { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronSignTx.address_n) + pub address_n: ::std::vec::Vec, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronSignTx.ref_block_bytes) + pub ref_block_bytes: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronSignTx.ref_block_hash) + pub ref_block_hash: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronSignTx.expiration) + pub expiration: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronSignTx.data) + pub data: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronSignTx.timestamp) + pub timestamp: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronSignTx.fee_limit) + pub fee_limit: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.tron.TronSignTx.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a TronSignTx { + fn default() -> &'a TronSignTx { + ::default_instance() + } +} + +impl TronSignTx { + pub fn new() -> TronSignTx { + ::std::default::Default::default() + } + + // required bytes ref_block_bytes = 2; + + pub fn ref_block_bytes(&self) -> &[u8] { + match self.ref_block_bytes.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_ref_block_bytes(&mut self) { + self.ref_block_bytes = ::std::option::Option::None; + } + + pub fn has_ref_block_bytes(&self) -> bool { + self.ref_block_bytes.is_some() + } + + // Param is passed by value, moved + pub fn set_ref_block_bytes(&mut self, v: ::std::vec::Vec) { + self.ref_block_bytes = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_ref_block_bytes(&mut self) -> &mut ::std::vec::Vec { + if self.ref_block_bytes.is_none() { + self.ref_block_bytes = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.ref_block_bytes.as_mut().unwrap() + } + + // Take field + pub fn take_ref_block_bytes(&mut self) -> ::std::vec::Vec { + self.ref_block_bytes.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required bytes ref_block_hash = 3; + + pub fn ref_block_hash(&self) -> &[u8] { + match self.ref_block_hash.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_ref_block_hash(&mut self) { + self.ref_block_hash = ::std::option::Option::None; + } + + pub fn has_ref_block_hash(&self) -> bool { + self.ref_block_hash.is_some() + } + + // Param is passed by value, moved + pub fn set_ref_block_hash(&mut self, v: ::std::vec::Vec) { + self.ref_block_hash = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_ref_block_hash(&mut self) -> &mut ::std::vec::Vec { + if self.ref_block_hash.is_none() { + self.ref_block_hash = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.ref_block_hash.as_mut().unwrap() + } + + // Take field + pub fn take_ref_block_hash(&mut self) -> ::std::vec::Vec { + self.ref_block_hash.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required sint64 expiration = 4; + + pub fn expiration(&self) -> i64 { + self.expiration.unwrap_or(0) + } + + pub fn clear_expiration(&mut self) { + self.expiration = ::std::option::Option::None; + } + + pub fn has_expiration(&self) -> bool { + self.expiration.is_some() + } + + // Param is passed by value, moved + pub fn set_expiration(&mut self, v: i64) { + self.expiration = ::std::option::Option::Some(v); + } + + // optional bytes data = 5; + + pub fn data(&self) -> &[u8] { + match self.data.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_data(&mut self) { + self.data = ::std::option::Option::None; + } + + pub fn has_data(&self) -> bool { + self.data.is_some() + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::vec::Vec) { + self.data = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { + if self.data.is_none() { + self.data = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.data.as_mut().unwrap() + } + + // Take field + pub fn take_data(&mut self) -> ::std::vec::Vec { + self.data.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required sint64 timestamp = 6; + + pub fn timestamp(&self) -> i64 { + self.timestamp.unwrap_or(0) + } + + pub fn clear_timestamp(&mut self) { + self.timestamp = ::std::option::Option::None; + } + + pub fn has_timestamp(&self) -> bool { + self.timestamp.is_some() + } + + // Param is passed by value, moved + pub fn set_timestamp(&mut self, v: i64) { + self.timestamp = ::std::option::Option::Some(v); + } + + // optional sint64 fee_limit = 7; + + pub fn fee_limit(&self) -> i64 { + self.fee_limit.unwrap_or(0) + } + + pub fn clear_fee_limit(&mut self) { + self.fee_limit = ::std::option::Option::None; + } + + pub fn has_fee_limit(&self) -> bool { + self.fee_limit.is_some() + } + + // Param is passed by value, moved + pub fn set_fee_limit(&mut self, v: i64) { + self.fee_limit = ::std::option::Option::Some(v); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(7); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "address_n", + |m: &TronSignTx| { &m.address_n }, + |m: &mut TronSignTx| { &mut m.address_n }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ref_block_bytes", + |m: &TronSignTx| { &m.ref_block_bytes }, + |m: &mut TronSignTx| { &mut m.ref_block_bytes }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ref_block_hash", + |m: &TronSignTx| { &m.ref_block_hash }, + |m: &mut TronSignTx| { &mut m.ref_block_hash }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "expiration", + |m: &TronSignTx| { &m.expiration }, + |m: &mut TronSignTx| { &mut m.expiration }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "data", + |m: &TronSignTx| { &m.data }, + |m: &mut TronSignTx| { &mut m.data }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "timestamp", + |m: &TronSignTx| { &m.timestamp }, + |m: &mut TronSignTx| { &mut m.timestamp }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "fee_limit", + |m: &TronSignTx| { &m.fee_limit }, + |m: &mut TronSignTx| { &mut m.fee_limit }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "TronSignTx", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for TronSignTx { + const NAME: &'static str = "TronSignTx"; + + fn is_initialized(&self) -> bool { + if self.ref_block_bytes.is_none() { + return false; + } + if self.ref_block_hash.is_none() { + return false; + } + if self.expiration.is_none() { + return false; + } + if self.timestamp.is_none() { + return false; + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + is.read_repeated_packed_uint32_into(&mut self.address_n)?; + }, + 8 => { + self.address_n.push(is.read_uint32()?); + }, + 18 => { + self.ref_block_bytes = ::std::option::Option::Some(is.read_bytes()?); + }, + 26 => { + self.ref_block_hash = ::std::option::Option::Some(is.read_bytes()?); + }, + 32 => { + self.expiration = ::std::option::Option::Some(is.read_sint64()?); + }, + 42 => { + self.data = ::std::option::Option::Some(is.read_bytes()?); + }, + 48 => { + self.timestamp = ::std::option::Option::Some(is.read_sint64()?); + }, + 56 => { + self.fee_limit = ::std::option::Option::Some(is.read_sint64()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + for value in &self.address_n { + my_size += ::protobuf::rt::uint32_size(1, *value); + }; + if let Some(v) = self.ref_block_bytes.as_ref() { + my_size += ::protobuf::rt::bytes_size(2, &v); + } + if let Some(v) = self.ref_block_hash.as_ref() { + my_size += ::protobuf::rt::bytes_size(3, &v); + } + if let Some(v) = self.expiration { + my_size += ::protobuf::rt::sint64_size(4, v); + } + if let Some(v) = self.data.as_ref() { + my_size += ::protobuf::rt::bytes_size(5, &v); + } + if let Some(v) = self.timestamp { + my_size += ::protobuf::rt::sint64_size(6, v); + } + if let Some(v) = self.fee_limit { + my_size += ::protobuf::rt::sint64_size(7, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + for v in &self.address_n { + os.write_uint32(1, *v)?; + }; + if let Some(v) = self.ref_block_bytes.as_ref() { + os.write_bytes(2, v)?; + } + if let Some(v) = self.ref_block_hash.as_ref() { + os.write_bytes(3, v)?; + } + if let Some(v) = self.expiration { + os.write_sint64(4, v)?; + } + if let Some(v) = self.data.as_ref() { + os.write_bytes(5, v)?; + } + if let Some(v) = self.timestamp { + os.write_sint64(6, v)?; + } + if let Some(v) = self.fee_limit { + os.write_sint64(7, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> TronSignTx { + TronSignTx::new() + } + + fn clear(&mut self) { + self.address_n.clear(); + self.ref_block_bytes = ::std::option::Option::None; + self.ref_block_hash = ::std::option::Option::None; + self.expiration = ::std::option::Option::None; + self.data = ::std::option::Option::None; + self.timestamp = ::std::option::Option::None; + self.fee_limit = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static TronSignTx { + static instance: TronSignTx = TronSignTx { + address_n: ::std::vec::Vec::new(), + ref_block_bytes: ::std::option::Option::None, + ref_block_hash: ::std::option::Option::None, + expiration: ::std::option::Option::None, + data: ::std::option::Option::None, + timestamp: ::std::option::Option::None, + fee_limit: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for TronSignTx { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("TronSignTx").unwrap()).clone() + } +} + +impl ::std::fmt::Display for TronSignTx { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for TronSignTx { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.tron.TronContractRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct TronContractRequest { + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.tron.TronContractRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a TronContractRequest { + fn default() -> &'a TronContractRequest { + ::default_instance() + } +} + +impl TronContractRequest { + pub fn new() -> TronContractRequest { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "TronContractRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for TronContractRequest { + const NAME: &'static str = "TronContractRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> TronContractRequest { + TronContractRequest::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static TronContractRequest { + static instance: TronContractRequest = TronContractRequest { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for TronContractRequest { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("TronContractRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for TronContractRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for TronContractRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.tron.TronTransferContract) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct TronTransferContract { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronTransferContract.owner_address) + pub owner_address: ::std::option::Option<::std::string::String>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronTransferContract.to_address) + pub to_address: ::std::option::Option<::std::string::String>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronTransferContract.amount) + pub amount: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.tron.TronTransferContract.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a TronTransferContract { + fn default() -> &'a TronTransferContract { + ::default_instance() + } +} + +impl TronTransferContract { + pub fn new() -> TronTransferContract { + ::std::default::Default::default() + } + + // required string owner_address = 1; + + pub fn owner_address(&self) -> &str { + match self.owner_address.as_ref() { + Some(v) => v, + None => "", + } + } + + pub fn clear_owner_address(&mut self) { + self.owner_address = ::std::option::Option::None; + } + + pub fn has_owner_address(&self) -> bool { + self.owner_address.is_some() + } + + // Param is passed by value, moved + pub fn set_owner_address(&mut self, v: ::std::string::String) { + self.owner_address = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_owner_address(&mut self) -> &mut ::std::string::String { + if self.owner_address.is_none() { + self.owner_address = ::std::option::Option::Some(::std::string::String::new()); + } + self.owner_address.as_mut().unwrap() + } + + // Take field + pub fn take_owner_address(&mut self) -> ::std::string::String { + self.owner_address.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // required string to_address = 2; + + pub fn to_address(&self) -> &str { + match self.to_address.as_ref() { + Some(v) => v, + None => "", + } + } + + pub fn clear_to_address(&mut self) { + self.to_address = ::std::option::Option::None; + } + + pub fn has_to_address(&self) -> bool { + self.to_address.is_some() + } + + // Param is passed by value, moved + pub fn set_to_address(&mut self, v: ::std::string::String) { + self.to_address = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_to_address(&mut self) -> &mut ::std::string::String { + if self.to_address.is_none() { + self.to_address = ::std::option::Option::Some(::std::string::String::new()); + } + self.to_address.as_mut().unwrap() + } + + // Take field + pub fn take_to_address(&mut self) -> ::std::string::String { + self.to_address.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // required sint64 amount = 3; + + pub fn amount(&self) -> i64 { + self.amount.unwrap_or(0) + } + + pub fn clear_amount(&mut self) { + self.amount = ::std::option::Option::None; + } + + pub fn has_amount(&self) -> bool { + self.amount.is_some() + } + + // Param is passed by value, moved + pub fn set_amount(&mut self, v: i64) { + self.amount = ::std::option::Option::Some(v); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "owner_address", + |m: &TronTransferContract| { &m.owner_address }, + |m: &mut TronTransferContract| { &mut m.owner_address }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "to_address", + |m: &TronTransferContract| { &m.to_address }, + |m: &mut TronTransferContract| { &mut m.to_address }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "amount", + |m: &TronTransferContract| { &m.amount }, + |m: &mut TronTransferContract| { &mut m.amount }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "TronTransferContract", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for TronTransferContract { + const NAME: &'static str = "TronTransferContract"; + + fn is_initialized(&self) -> bool { + if self.owner_address.is_none() { + return false; + } + if self.to_address.is_none() { + return false; + } + if self.amount.is_none() { + return false; + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.owner_address = ::std::option::Option::Some(is.read_string()?); + }, + 18 => { + self.to_address = ::std::option::Option::Some(is.read_string()?); + }, + 24 => { + self.amount = ::std::option::Option::Some(is.read_sint64()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.owner_address.as_ref() { + my_size += ::protobuf::rt::string_size(1, &v); + } + if let Some(v) = self.to_address.as_ref() { + my_size += ::protobuf::rt::string_size(2, &v); + } + if let Some(v) = self.amount { + my_size += ::protobuf::rt::sint64_size(3, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.owner_address.as_ref() { + os.write_string(1, v)?; + } + if let Some(v) = self.to_address.as_ref() { + os.write_string(2, v)?; + } + if let Some(v) = self.amount { + os.write_sint64(3, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> TronTransferContract { + TronTransferContract::new() + } + + fn clear(&mut self) { + self.owner_address = ::std::option::Option::None; + self.to_address = ::std::option::Option::None; + self.amount = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static TronTransferContract { + static instance: TronTransferContract = TronTransferContract { + owner_address: ::std::option::Option::None, + to_address: ::std::option::Option::None, + amount: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for TronTransferContract { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("TronTransferContract").unwrap()).clone() + } +} + +impl ::std::fmt::Display for TronTransferContract { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for TronTransferContract { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.tron.TronSignature) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct TronSignature { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronSignature.signature) + pub signature: ::std::option::Option<::std::vec::Vec>, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.tron.TronSignature.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a TronSignature { + fn default() -> &'a TronSignature { + ::default_instance() + } +} + +impl TronSignature { + pub fn new() -> TronSignature { + ::std::default::Default::default() + } + + // required bytes signature = 1; + + pub fn signature(&self) -> &[u8] { + match self.signature.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_signature(&mut self) { + self.signature = ::std::option::Option::None; + } + + pub fn has_signature(&self) -> bool { + self.signature.is_some() + } + + // Param is passed by value, moved + pub fn set_signature(&mut self, v: ::std::vec::Vec) { + self.signature = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_signature(&mut self) -> &mut ::std::vec::Vec { + if self.signature.is_none() { + self.signature = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.signature.as_mut().unwrap() + } + + // Take field + pub fn take_signature(&mut self) -> ::std::vec::Vec { + self.signature.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "signature", + |m: &TronSignature| { &m.signature }, + |m: &mut TronSignature| { &mut m.signature }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "TronSignature", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for TronSignature { + const NAME: &'static str = "TronSignature"; + + fn is_initialized(&self) -> bool { + if self.signature.is_none() { + return false; + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.signature = ::std::option::Option::Some(is.read_bytes()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.signature.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.signature.as_ref() { + os.write_bytes(1, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> TronSignature { + TronSignature::new() + } + + fn clear(&mut self) { + self.signature = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static TronSignature { + static instance: TronSignature = TronSignature { + signature: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for TronSignature { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("TronSignature").unwrap()).clone() + } +} + +impl ::std::fmt::Display for TronSignature { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for TronSignature { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.tron.TronRawTransaction) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct TronRawTransaction { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.ref_block_bytes) + pub ref_block_bytes: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.ref_block_hash) + pub ref_block_hash: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.expiration) + pub expiration: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.data) + pub data: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.contract) + pub contract: ::std::vec::Vec, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.timestamp) + pub timestamp: ::std::option::Option, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.fee_limit) + pub fee_limit: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.tron.TronRawTransaction.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a TronRawTransaction { + fn default() -> &'a TronRawTransaction { + ::default_instance() + } +} + +impl TronRawTransaction { + pub fn new() -> TronRawTransaction { + ::std::default::Default::default() + } + + // required bytes ref_block_bytes = 1; + + pub fn ref_block_bytes(&self) -> &[u8] { + match self.ref_block_bytes.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_ref_block_bytes(&mut self) { + self.ref_block_bytes = ::std::option::Option::None; + } + + pub fn has_ref_block_bytes(&self) -> bool { + self.ref_block_bytes.is_some() + } + + // Param is passed by value, moved + pub fn set_ref_block_bytes(&mut self, v: ::std::vec::Vec) { + self.ref_block_bytes = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_ref_block_bytes(&mut self) -> &mut ::std::vec::Vec { + if self.ref_block_bytes.is_none() { + self.ref_block_bytes = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.ref_block_bytes.as_mut().unwrap() + } + + // Take field + pub fn take_ref_block_bytes(&mut self) -> ::std::vec::Vec { + self.ref_block_bytes.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required bytes ref_block_hash = 4; + + pub fn ref_block_hash(&self) -> &[u8] { + match self.ref_block_hash.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_ref_block_hash(&mut self) { + self.ref_block_hash = ::std::option::Option::None; + } + + pub fn has_ref_block_hash(&self) -> bool { + self.ref_block_hash.is_some() + } + + // Param is passed by value, moved + pub fn set_ref_block_hash(&mut self, v: ::std::vec::Vec) { + self.ref_block_hash = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_ref_block_hash(&mut self) -> &mut ::std::vec::Vec { + if self.ref_block_hash.is_none() { + self.ref_block_hash = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.ref_block_hash.as_mut().unwrap() + } + + // Take field + pub fn take_ref_block_hash(&mut self) -> ::std::vec::Vec { + self.ref_block_hash.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required uint64 expiration = 8; + + pub fn expiration(&self) -> u64 { + self.expiration.unwrap_or(0) + } + + pub fn clear_expiration(&mut self) { + self.expiration = ::std::option::Option::None; + } + + pub fn has_expiration(&self) -> bool { + self.expiration.is_some() + } + + // Param is passed by value, moved + pub fn set_expiration(&mut self, v: u64) { + self.expiration = ::std::option::Option::Some(v); + } + + // optional bytes data = 10; + + pub fn data(&self) -> &[u8] { + match self.data.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_data(&mut self) { + self.data = ::std::option::Option::None; + } + + pub fn has_data(&self) -> bool { + self.data.is_some() + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::vec::Vec) { + self.data = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { + if self.data.is_none() { + self.data = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.data.as_mut().unwrap() + } + + // Take field + pub fn take_data(&mut self) -> ::std::vec::Vec { + self.data.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required uint64 timestamp = 14; + + pub fn timestamp(&self) -> u64 { + self.timestamp.unwrap_or(0) + } + + pub fn clear_timestamp(&mut self) { + self.timestamp = ::std::option::Option::None; + } + + pub fn has_timestamp(&self) -> bool { + self.timestamp.is_some() + } + + // Param is passed by value, moved + pub fn set_timestamp(&mut self, v: u64) { + self.timestamp = ::std::option::Option::Some(v); + } + + // optional uint64 fee_limit = 18; + + pub fn fee_limit(&self) -> u64 { + self.fee_limit.unwrap_or(0) + } + + pub fn clear_fee_limit(&mut self) { + self.fee_limit = ::std::option::Option::None; + } + + pub fn has_fee_limit(&self) -> bool { + self.fee_limit.is_some() + } + + // Param is passed by value, moved + pub fn set_fee_limit(&mut self, v: u64) { + self.fee_limit = ::std::option::Option::Some(v); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(7); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ref_block_bytes", + |m: &TronRawTransaction| { &m.ref_block_bytes }, + |m: &mut TronRawTransaction| { &mut m.ref_block_bytes }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ref_block_hash", + |m: &TronRawTransaction| { &m.ref_block_hash }, + |m: &mut TronRawTransaction| { &mut m.ref_block_hash }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "expiration", + |m: &TronRawTransaction| { &m.expiration }, + |m: &mut TronRawTransaction| { &mut m.expiration }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "data", + |m: &TronRawTransaction| { &m.data }, + |m: &mut TronRawTransaction| { &mut m.data }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "contract", + |m: &TronRawTransaction| { &m.contract }, + |m: &mut TronRawTransaction| { &mut m.contract }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "timestamp", + |m: &TronRawTransaction| { &m.timestamp }, + |m: &mut TronRawTransaction| { &mut m.timestamp }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "fee_limit", + |m: &TronRawTransaction| { &m.fee_limit }, + |m: &mut TronRawTransaction| { &mut m.fee_limit }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "TronRawTransaction", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for TronRawTransaction { + const NAME: &'static str = "TronRawTransaction"; + + fn is_initialized(&self) -> bool { + if self.ref_block_bytes.is_none() { + return false; + } + if self.ref_block_hash.is_none() { + return false; + } + if self.expiration.is_none() { + return false; + } + if self.timestamp.is_none() { + return false; + } + for v in &self.contract { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.ref_block_bytes = ::std::option::Option::Some(is.read_bytes()?); + }, + 34 => { + self.ref_block_hash = ::std::option::Option::Some(is.read_bytes()?); + }, + 64 => { + self.expiration = ::std::option::Option::Some(is.read_uint64()?); + }, + 82 => { + self.data = ::std::option::Option::Some(is.read_bytes()?); + }, + 90 => { + self.contract.push(is.read_message()?); + }, + 112 => { + self.timestamp = ::std::option::Option::Some(is.read_uint64()?); + }, + 144 => { + self.fee_limit = ::std::option::Option::Some(is.read_uint64()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.ref_block_bytes.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + if let Some(v) = self.ref_block_hash.as_ref() { + my_size += ::protobuf::rt::bytes_size(4, &v); + } + if let Some(v) = self.expiration { + my_size += ::protobuf::rt::uint64_size(8, v); + } + if let Some(v) = self.data.as_ref() { + my_size += ::protobuf::rt::bytes_size(10, &v); + } + for value in &self.contract { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + if let Some(v) = self.timestamp { + my_size += ::protobuf::rt::uint64_size(14, v); + } + if let Some(v) = self.fee_limit { + my_size += ::protobuf::rt::uint64_size(18, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.ref_block_bytes.as_ref() { + os.write_bytes(1, v)?; + } + if let Some(v) = self.ref_block_hash.as_ref() { + os.write_bytes(4, v)?; + } + if let Some(v) = self.expiration { + os.write_uint64(8, v)?; + } + if let Some(v) = self.data.as_ref() { + os.write_bytes(10, v)?; + } + for v in &self.contract { + ::protobuf::rt::write_message_field_with_cached_size(11, v, os)?; + }; + if let Some(v) = self.timestamp { + os.write_uint64(14, v)?; + } + if let Some(v) = self.fee_limit { + os.write_uint64(18, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> TronRawTransaction { + TronRawTransaction::new() + } + + fn clear(&mut self) { + self.ref_block_bytes = ::std::option::Option::None; + self.ref_block_hash = ::std::option::Option::None; + self.expiration = ::std::option::Option::None; + self.data = ::std::option::Option::None; + self.contract.clear(); + self.timestamp = ::std::option::Option::None; + self.fee_limit = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static TronRawTransaction { + static instance: TronRawTransaction = TronRawTransaction { + ref_block_bytes: ::std::option::Option::None, + ref_block_hash: ::std::option::Option::None, + expiration: ::std::option::Option::None, + data: ::std::option::Option::None, + contract: ::std::vec::Vec::new(), + timestamp: ::std::option::Option::None, + fee_limit: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for TronRawTransaction { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("TronRawTransaction").unwrap()).clone() + } +} + +impl ::std::fmt::Display for TronRawTransaction { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for TronRawTransaction { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +/// Nested message and enums of message `TronRawTransaction` +pub mod tron_raw_transaction { + // @@protoc_insertion_point(message:hw.trezor.messages.tron.TronRawTransaction.TronRawContract) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct TronRawContract { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.type) + pub type_: ::std::option::Option<::protobuf::EnumOrUnknown>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.parameter) + pub parameter: ::protobuf::MessageField, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a TronRawContract { + fn default() -> &'a TronRawContract { + ::default_instance() + } + } + + impl TronRawContract { + pub fn new() -> TronRawContract { + ::std::default::Default::default() + } + + // required .hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawContractType type = 1; + + pub fn type_(&self) -> tron_raw_contract::TronRawContractType { + match self.type_ { + Some(e) => e.enum_value_or(tron_raw_contract::TronRawContractType::TransferContract), + None => tron_raw_contract::TronRawContractType::TransferContract, + } + } + + pub fn clear_type_(&mut self) { + self.type_ = ::std::option::Option::None; + } + + pub fn has_type(&self) -> bool { + self.type_.is_some() + } + + // Param is passed by value, moved + pub fn set_type(&mut self, v: tron_raw_contract::TronRawContractType) { + self.type_ = ::std::option::Option::Some(::protobuf::EnumOrUnknown::new(v)); + } + + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "type", + |m: &TronRawContract| { &m.type_ }, + |m: &mut TronRawContract| { &mut m.type_ }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, tron_raw_contract::TronRawParameter>( + "parameter", + |m: &TronRawContract| { &m.parameter }, + |m: &mut TronRawContract| { &mut m.parameter }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "TronRawTransaction.TronRawContract", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for TronRawContract { + const NAME: &'static str = "TronRawContract"; + + fn is_initialized(&self) -> bool { + if self.type_.is_none() { + return false; + } + if self.parameter.is_none() { + return false; + } + for v in &self.parameter { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 8 => { + self.type_ = ::std::option::Option::Some(is.read_enum_or_unknown()?); + }, + 18 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.parameter)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.type_ { + my_size += ::protobuf::rt::int32_size(1, v.value()); + } + if let Some(v) = self.parameter.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.type_ { + os.write_enum(1, ::protobuf::EnumOrUnknown::value(&v))?; + } + if let Some(v) = self.parameter.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> TronRawContract { + TronRawContract::new() + } + + fn clear(&mut self) { + self.type_ = ::std::option::Option::None; + self.parameter.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static TronRawContract { + static instance: TronRawContract = TronRawContract { + type_: ::std::option::Option::None, + parameter: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for TronRawContract { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().message_by_package_relative_name("TronRawTransaction.TronRawContract").unwrap()).clone() + } + } + + impl ::std::fmt::Display for TronRawContract { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for TronRawContract { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; + } + + /// Nested message and enums of message `TronRawContract` + pub mod tron_raw_contract { + // @@protoc_insertion_point(message:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawTransferContract) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct TronRawTransferContract { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawTransferContract.owner_address) + pub owner_address: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawTransferContract.to_address) + pub to_address: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawTransferContract.amount) + pub amount: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawTransferContract.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a TronRawTransferContract { + fn default() -> &'a TronRawTransferContract { + ::default_instance() + } + } + + impl TronRawTransferContract { + pub fn new() -> TronRawTransferContract { + ::std::default::Default::default() + } + + // required bytes owner_address = 1; + + pub fn owner_address(&self) -> &[u8] { + match self.owner_address.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_owner_address(&mut self) { + self.owner_address = ::std::option::Option::None; + } + + pub fn has_owner_address(&self) -> bool { + self.owner_address.is_some() + } + + // Param is passed by value, moved + pub fn set_owner_address(&mut self, v: ::std::vec::Vec) { + self.owner_address = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_owner_address(&mut self) -> &mut ::std::vec::Vec { + if self.owner_address.is_none() { + self.owner_address = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.owner_address.as_mut().unwrap() + } + + // Take field + pub fn take_owner_address(&mut self) -> ::std::vec::Vec { + self.owner_address.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required bytes to_address = 2; + + pub fn to_address(&self) -> &[u8] { + match self.to_address.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_to_address(&mut self) { + self.to_address = ::std::option::Option::None; + } + + pub fn has_to_address(&self) -> bool { + self.to_address.is_some() + } + + // Param is passed by value, moved + pub fn set_to_address(&mut self, v: ::std::vec::Vec) { + self.to_address = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_to_address(&mut self) -> &mut ::std::vec::Vec { + if self.to_address.is_none() { + self.to_address = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.to_address.as_mut().unwrap() + } + + // Take field + pub fn take_to_address(&mut self) -> ::std::vec::Vec { + self.to_address.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // required uint64 amount = 3; + + pub fn amount(&self) -> u64 { + self.amount.unwrap_or(0) + } + + pub fn clear_amount(&mut self) { + self.amount = ::std::option::Option::None; + } + + pub fn has_amount(&self) -> bool { + self.amount.is_some() + } + + // Param is passed by value, moved + pub fn set_amount(&mut self, v: u64) { + self.amount = ::std::option::Option::Some(v); + } + + pub(in super::super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "owner_address", + |m: &TronRawTransferContract| { &m.owner_address }, + |m: &mut TronRawTransferContract| { &mut m.owner_address }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "to_address", + |m: &TronRawTransferContract| { &m.to_address }, + |m: &mut TronRawTransferContract| { &mut m.to_address }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "amount", + |m: &TronRawTransferContract| { &m.amount }, + |m: &mut TronRawTransferContract| { &mut m.amount }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "TronRawTransaction.TronRawContract.TronRawTransferContract", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for TronRawTransferContract { + const NAME: &'static str = "TronRawTransferContract"; + + fn is_initialized(&self) -> bool { + if self.owner_address.is_none() { + return false; + } + if self.to_address.is_none() { + return false; + } + if self.amount.is_none() { + return false; + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.owner_address = ::std::option::Option::Some(is.read_bytes()?); + }, + 18 => { + self.to_address = ::std::option::Option::Some(is.read_bytes()?); + }, + 24 => { + self.amount = ::std::option::Option::Some(is.read_uint64()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.owner_address.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + if let Some(v) = self.to_address.as_ref() { + my_size += ::protobuf::rt::bytes_size(2, &v); + } + if let Some(v) = self.amount { + my_size += ::protobuf::rt::uint64_size(3, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.owner_address.as_ref() { + os.write_bytes(1, v)?; + } + if let Some(v) = self.to_address.as_ref() { + os.write_bytes(2, v)?; + } + if let Some(v) = self.amount { + os.write_uint64(3, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> TronRawTransferContract { + TronRawTransferContract::new() + } + + fn clear(&mut self) { + self.owner_address = ::std::option::Option::None; + self.to_address = ::std::option::Option::None; + self.amount = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static TronRawTransferContract { + static instance: TronRawTransferContract = TronRawTransferContract { + owner_address: ::std::option::Option::None, + to_address: ::std::option::Option::None, + amount: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for TronRawTransferContract { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::super::file_descriptor().message_by_package_relative_name("TronRawTransaction.TronRawContract.TronRawTransferContract").unwrap()).clone() + } + } + + impl ::std::fmt::Display for TronRawTransferContract { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for TronRawTransferContract { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; + } + + // @@protoc_insertion_point(message:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawParameter) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct TronRawParameter { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawParameter.type_url) + pub type_url: ::std::option::Option<::std::string::String>, + // @@protoc_insertion_point(field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawParameter.value) + pub value: ::std::option::Option<::std::vec::Vec>, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawParameter.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a TronRawParameter { + fn default() -> &'a TronRawParameter { + ::default_instance() + } + } + + impl TronRawParameter { + pub fn new() -> TronRawParameter { + ::std::default::Default::default() + } + + // required string type_url = 1; + + pub fn type_url(&self) -> &str { + match self.type_url.as_ref() { + Some(v) => v, + None => "", + } + } + + pub fn clear_type_url(&mut self) { + self.type_url = ::std::option::Option::None; + } + + pub fn has_type_url(&self) -> bool { + self.type_url.is_some() + } + + // Param is passed by value, moved + pub fn set_type_url(&mut self, v: ::std::string::String) { + self.type_url = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_type_url(&mut self) -> &mut ::std::string::String { + if self.type_url.is_none() { + self.type_url = ::std::option::Option::Some(::std::string::String::new()); + } + self.type_url.as_mut().unwrap() + } + + // Take field + pub fn take_type_url(&mut self) -> ::std::string::String { + self.type_url.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // required bytes value = 2; + + pub fn value(&self) -> &[u8] { + match self.value.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_value(&mut self) { + self.value = ::std::option::Option::None; + } + + pub fn has_value(&self) -> bool { + self.value.is_some() + } + + // Param is passed by value, moved + pub fn set_value(&mut self, v: ::std::vec::Vec) { + self.value = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_value(&mut self) -> &mut ::std::vec::Vec { + if self.value.is_none() { + self.value = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.value.as_mut().unwrap() + } + + // Take field + pub fn take_value(&mut self) -> ::std::vec::Vec { + self.value.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + pub(in super::super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "type_url", + |m: &TronRawParameter| { &m.type_url }, + |m: &mut TronRawParameter| { &mut m.type_url }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "value", + |m: &TronRawParameter| { &m.value }, + |m: &mut TronRawParameter| { &mut m.value }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "TronRawTransaction.TronRawContract.TronRawParameter", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for TronRawParameter { + const NAME: &'static str = "TronRawParameter"; + + fn is_initialized(&self) -> bool { + if self.type_url.is_none() { + return false; + } + if self.value.is_none() { + return false; + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.type_url = ::std::option::Option::Some(is.read_string()?); + }, + 18 => { + self.value = ::std::option::Option::Some(is.read_bytes()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.type_url.as_ref() { + my_size += ::protobuf::rt::string_size(1, &v); + } + if let Some(v) = self.value.as_ref() { + my_size += ::protobuf::rt::bytes_size(2, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.type_url.as_ref() { + os.write_string(1, v)?; + } + if let Some(v) = self.value.as_ref() { + os.write_bytes(2, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> TronRawParameter { + TronRawParameter::new() + } + + fn clear(&mut self) { + self.type_url = ::std::option::Option::None; + self.value = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static TronRawParameter { + static instance: TronRawParameter = TronRawParameter { + type_url: ::std::option::Option::None, + value: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for TronRawParameter { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::super::file_descriptor().message_by_package_relative_name("TronRawTransaction.TronRawContract.TronRawParameter").unwrap()).clone() + } + } + + impl ::std::fmt::Display for TronRawParameter { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for TronRawParameter { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; + } + + #[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)] + // @@protoc_insertion_point(enum:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawContractType) + pub enum TronRawContractType { + // @@protoc_insertion_point(enum_value:hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawContractType.TransferContract) + TransferContract = 1, + } + + impl ::protobuf::Enum for TronRawContractType { + const NAME: &'static str = "TronRawContractType"; + + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 1 => ::std::option::Option::Some(TronRawContractType::TransferContract), + _ => ::std::option::Option::None + } + } + + fn from_str(str: &str) -> ::std::option::Option { + match str { + "TransferContract" => ::std::option::Option::Some(TronRawContractType::TransferContract), + _ => ::std::option::Option::None + } + } + + const VALUES: &'static [TronRawContractType] = &[ + TronRawContractType::TransferContract, + ]; + } + + impl ::protobuf::EnumFull for TronRawContractType { + fn enum_descriptor() -> ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::super::file_descriptor().enum_by_package_relative_name("TronRawTransaction.TronRawContract.TronRawContractType").unwrap()).clone() + } + + fn descriptor(&self) -> ::protobuf::reflect::EnumValueDescriptor { + let index = match self { + TronRawContractType::TransferContract => 0, + }; + Self::enum_descriptor().value_by_index(index) + } + } + + // Note, `Default` is implemented although default value is not 0 + impl ::std::default::Default for TronRawContractType { + fn default() -> Self { + TronRawContractType::TransferContract + } + } + + impl TronRawContractType { + pub(in super::super) fn generated_enum_descriptor_data() -> ::protobuf::reflect::GeneratedEnumDescriptorData { + ::protobuf::reflect::GeneratedEnumDescriptorData::new::("TronRawTransaction.TronRawContract.TronRawContractType") + } + } + } +} + static file_descriptor_proto_data: &'static [u8] = b"\ \n\x13messages-tron.proto\x12\x17hw.trezor.messages.tron\"l\n\x0eTronGet\ Address\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12!\n\x0cs\ how_display\x18\x02\x20\x01(\x08R\x0bshowDisplay\x12\x1a\n\x08chunkify\ \x18\x03\x20\x01(\x08R\x08chunkify\"9\n\x0bTronAddress\x12\x18\n\x07addr\ ess\x18\x01\x20\x02(\tR\x07address\x12\x10\n\x03mac\x18\x02\x20\x01(\x0c\ - R\x03macB8\n#com.satoshilabs.trezor.lib.protobufB\x11TrezorMessageTron\ + R\x03mac\"\xe6\x01\n\nTronSignTx\x12\x1b\n\taddress_n\x18\x01\x20\x03(\r\ + R\x08addressN\x12&\n\x0fref_block_bytes\x18\x02\x20\x02(\x0cR\rrefBlockB\ + ytes\x12$\n\x0eref_block_hash\x18\x03\x20\x02(\x0cR\x0crefBlockHash\x12\ + \x1e\n\nexpiration\x18\x04\x20\x02(\x12R\nexpiration\x12\x12\n\x04data\ + \x18\x05\x20\x01(\x0cR\x04data\x12\x1c\n\ttimestamp\x18\x06\x20\x02(\x12\ + R\ttimestamp\x12\x1b\n\tfee_limit\x18\x07\x20\x01(\x12R\x08feeLimit\"\ + \x15\n\x13TronContractRequest\"r\n\x14TronTransferContract\x12#\n\rowner\ + _address\x18\x01\x20\x02(\tR\x0cownerAddress\x12\x1d\n\nto_address\x18\ + \x02\x20\x02(\tR\ttoAddress\x12\x16\n\x06amount\x18\x03\x20\x02(\x12R\ + \x06amount\"-\n\rTronSignature\x12\x1c\n\tsignature\x18\x01\x20\x02(\x0c\ + R\tsignature\"\xf8\x05\n\x12TronRawTransaction\x12&\n\x0fref_block_bytes\ + \x18\x01\x20\x02(\x0cR\rrefBlockBytes\x12$\n\x0eref_block_hash\x18\x04\ + \x20\x02(\x0cR\x0crefBlockHash\x12\x1e\n\nexpiration\x18\x08\x20\x02(\ + \x04R\nexpiration\x12\x12\n\x04data\x18\n\x20\x01(\x0cR\x04data\x12W\n\ + \x08contract\x18\x0b\x20\x03(\x0b2;.hw.trezor.messages.tron.TronRawTrans\ + action.TronRawContractR\x08contract\x12\x1c\n\ttimestamp\x18\x0e\x20\x02\ + (\x04R\ttimestamp\x12\x1b\n\tfee_limit\x18\x12\x20\x01(\x04R\x08feeLimit\ + \x1a\xcb\x03\n\x0fTronRawContract\x12c\n\x04type\x18\x01\x20\x02(\x0e2O.\ + hw.trezor.messages.tron.TronRawTransaction.TronRawContract.TronRawContra\ + ctTypeR\x04type\x12j\n\tparameter\x18\x02\x20\x02(\x0b2L.hw.trezor.messa\ + ges.tron.TronRawTransaction.TronRawContract.TronRawParameterR\tparameter\ + \x1au\n\x17TronRawTransferContract\x12#\n\rowner_address\x18\x01\x20\x02\ + (\x0cR\x0cownerAddress\x12\x1d\n\nto_address\x18\x02\x20\x02(\x0cR\ttoAd\ + dress\x12\x16\n\x06amount\x18\x03\x20\x02(\x04R\x06amount\x1aC\n\x10Tron\ + RawParameter\x12\x19\n\x08type_url\x18\x01\x20\x02(\tR\x07typeUrl\x12\ + \x14\n\x05value\x18\x02\x20\x02(\x0cR\x05value\"+\n\x13TronRawContractTy\ + pe\x12\x14\n\x10TransferContract\x10\x01B8\n#com.satoshilabs.trezor.lib.\ + protobufB\x11TrezorMessageTron\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -462,10 +2550,19 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { file_descriptor.get(|| { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(0); - let mut messages = ::std::vec::Vec::with_capacity(2); + let mut messages = ::std::vec::Vec::with_capacity(10); messages.push(TronGetAddress::generated_message_descriptor_data()); messages.push(TronAddress::generated_message_descriptor_data()); - let mut enums = ::std::vec::Vec::with_capacity(0); + messages.push(TronSignTx::generated_message_descriptor_data()); + messages.push(TronContractRequest::generated_message_descriptor_data()); + messages.push(TronTransferContract::generated_message_descriptor_data()); + messages.push(TronSignature::generated_message_descriptor_data()); + messages.push(TronRawTransaction::generated_message_descriptor_data()); + messages.push(tron_raw_transaction::TronRawContract::generated_message_descriptor_data()); + messages.push(tron_raw_transaction::tron_raw_contract::TronRawTransferContract::generated_message_descriptor_data()); + messages.push(tron_raw_transaction::tron_raw_contract::TronRawParameter::generated_message_descriptor_data()); + let mut enums = ::std::vec::Vec::with_capacity(1); + enums.push(tron_raw_transaction::tron_raw_contract::TronRawContractType::generated_enum_descriptor_data()); ::protobuf::reflect::GeneratedFileDescriptor::new_generated( file_descriptor_proto(), deps, diff --git a/tests/device_tests/tron/test_sign_tx.py b/tests/device_tests/tron/test_sign_tx.py new file mode 100644 index 00000000000..58aaaa02fe2 --- /dev/null +++ b/tests/device_tests/tron/test_sign_tx.py @@ -0,0 +1,33 @@ +import binascii + +import pytest + +from trezorlib import messages, protobuf, tron +from trezorlib.debuglink import TrezorClientDebugLink as Client +from trezorlib.tools import parse_path + +from ...common import parametrize_using_common_fixtures + +pytestmark = [pytest.mark.altcoin, pytest.mark.tron, pytest.mark.models("core")] + + +@parametrize_using_common_fixtures("tron/sign_tx.json") +def test_sign_tx(client: Client, parameters, result): + def make_contract(contract): + type_name = contract["_message_type"] + assert type_name.startswith("Tron") and type_name.endswith("Contract") + cls = getattr(messages, type_name) + return protobuf.dict_to_proto(cls, contract) + + address_n = parse_path(parameters["address_n"]) + tx = protobuf.dict_to_proto(messages.TronSignTx, parameters["tx"]) + contract = make_contract(parameters["contract"]) + + parsed_tx, parsed_contract = tron.from_raw_data( + bytes.fromhex(parameters["raw_data_hex"]) + ) + assert parsed_tx == tx + assert parsed_contract == contract + + response = tron.sign_tx(client, tx, contract, address_n) + assert response.signature == binascii.unhexlify(result["signature"])