feat(tron): add TransferContract support

Allows native TRX transfer
[no changelog]

Co-authored-by: PrisionMike <su.sh2396@gmail.com>
This commit is contained in:
Jun Luo
2025-12-20 02:16:05 +01:00
committed by Suyash Shandilya
parent 3c3a9ee627
commit 4375c211f9
41 changed files with 3204 additions and 157 deletions

View File

@@ -103,5 +103,12 @@
"slip44": 501,
"curve": "ed25519",
"decimals": 9
},
{
"name": "Tron",
"shortcut": "TRX",
"slip44": 195,
"curve": "secp256k1",
"decimals": 6
}
]

View File

@@ -115,7 +115,8 @@
"misc:XTZ": "not implemented",
"misc:tADA": "not implemented",
"misc:tXRP": "not implemented",
"eth:tHOL:17000": "Deprecated testnet"
"eth:tHOL:17000": "Deprecated testnet",
"misc:TRX": "not implemented"
}
},
"T2B1": {
@@ -234,7 +235,8 @@
"nem:PAC:CHS": "not for T2B1 (#2793)",
"nem:PAC:HRT": "not for T2B1 (#2793)",
"nem:XEM": "not for T2B1 (#2793)",
"eth:tHOL:17000": "Deprecated testnet"
"eth:tHOL:17000": "Deprecated testnet",
"misc:TRX": "WIP: Partial support in Debug build"
}
},
"T2T1": {
@@ -353,7 +355,8 @@
"bitcoin:TRC": "address_type collides with Bitcoin",
"bitcoin:tPART": "incompatible fork",
"misc:LSK": "Incompatible mainnet hard-fork",
"eth:tHOL:17000": "Deprecated testnet"
"eth:tHOL:17000": "Deprecated testnet",
"misc:TRX": "WIP: Partial support in Debug build"
}
},
"T3B1": {
@@ -472,7 +475,8 @@
"nem:PAC:CHS": "not for T3B1 (#2793)",
"nem:PAC:HRT": "not for T3B1 (#2793)",
"nem:XEM": "not for T3B1 (#2793)",
"eth:tHOL:17000": "Deprecated testnet"
"eth:tHOL:17000": "Deprecated testnet",
"misc:TRX": "WIP: Partial support in Debug build"
}
},
"T3T1": {
@@ -591,7 +595,8 @@
"nem:PAC:CHS": "not for T3T1 (#2793)",
"nem:PAC:HRT": "not for T3T1 (#2793)",
"nem:XEM": "not for T3T1 (#2793)",
"eth:tHOL:17000": "Deprecated testnet"
"eth:tHOL:17000": "Deprecated testnet",
"misc:TRX": "WIP: Partial support in Debug build"
}
},
"T3W1": {
@@ -710,7 +715,8 @@
"nem:PAC:CHS": "not for T3W1 (#2793)",
"nem:PAC:HRT": "not for T3W1 (#2793)",
"nem:XEM": "not for T3W1 (#2793)",
"eth:tHOL:17000": "Deprecated testnet"
"eth:tHOL:17000": "Deprecated testnet",
"misc:TRX": "WIP: Partial support in Debug build"
}
},
@@ -830,7 +836,8 @@
"nem:PAC:CHS": "not for T3W1 (#2793)",
"nem:PAC:HRT": "not for T3W1 (#2793)",
"nem:XEM": "not for T3W1 (#2793)",
"eth:tHOL:17000": "Deprecated testnet"
"eth:tHOL:17000": "Deprecated testnet",
"misc:TRX": "WIP: Partial support in Debug build"
}
},
@@ -950,7 +957,8 @@
"nem:PAC:CHS": "not for T3W1 (#2793)",
"nem:PAC:HRT": "not for T3W1 (#2793)",
"nem:XEM": "not for T3W1 (#2793)",
"eth:tHOL:17000": "Deprecated testnet"
"eth:tHOL:17000": "Deprecated testnet",
"misc:TRX": "WIP: Partial support in Debug build"
}
}
}

View File

@@ -176,6 +176,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;
}
}

View File

@@ -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,82 @@ message TronGetAddress {
* @end
*/
message TronAddress {
required string address = 1; // Tron address in base58_checked encoding
required string address = 1; // Tron address in Base58Check encoding
optional bytes mac = 2; // Address authentication code
}
/**
* Request: ask device to sign Tron transaction
* @start
* @next TronContractRequest
*/
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; // Not TRX. Maximum Energy cost. Only for deploying or triggering smart contracts.
}
/**
* 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
*/
// https://github.com/tronprotocol/protocol/blob/37bb922a9967bbbef1e84de1c9e5cda56a2d7998/core/contract/balance_contract.proto#L32-L36
message TronTransferContract {
// https://developers.tron.network/docs/tron-contracttype#2-transfercontract
required bytes owner_address = 1; // Sender's address, Base58Check encoding
required bytes to_address = 2; // Recipient's address, Base58Check encoding
required uint64 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 {
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
}
enum TronRawContractType {
TransferContract = 1;
}
required TronRawContractType type = 1;
required TronRawParameter parameter = 2;
}
}

View File

@@ -352,6 +352,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];

222
common/tests/fixtures/tron/sign_tx.json vendored Normal file
View File

@@ -0,0 +1,222 @@
{
"comment": "raw field is used only for debugging. TODO: Remove raw field",
"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": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58",
"to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283",
"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_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": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58",
"to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283",
"amount": 9223372036854775807
},
"raw_data_hex": "0a020fc422089643b084bc8b5cde4080abffe980335a6d080112690a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412380a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318ffffffffffffffff7f70adde8beb8033",
"comment": "TronWeb JavaScript SDK does not support big integers"
},
"result": {
"signature": "36db819a6c50b8c770ff1067a2753692fa8c8bfa7efde8ddfc2f891f7053d9955f6ffd0ee7d6217b448ac3515d97f6877159b721f2a78da78d1fcc10c1019dd51b"
}
},
{
"name": "Note_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": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58",
"to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283",
"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": "Note_bad_utf8_bytes",
"parameters": {
"address_n": "m/44'/195'/0'/0/0",
"tx": {
"ref_block_bytes": "ea2a",
"ref_block_hash": "d43320ee5a8b677f",
"expiration": 1752563334000,
"timestamp": 1752563274000,
"data": "deaddeaddeaddeaddeaddeaddeaddeaddead"
},
"contract": {
"_message_type": "TronTransferContract",
"owner_address": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58",
"to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283",
"amount": 18123456
},
"raw_data_hex": "0a02ea2a2208d43320ee5a8b677f40f0f6a8e780335212deaddeaddeaddeaddeaddeaddeaddeaddead5a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d2087090a2a5e78033",
"raw": {
"txID": "b7922b85edb82ea58f4510d46b0ad2dd5fb112fb7ee89fc39590c7147f3f1a29",
"raw_data": {
"data": "deaddeaddeaddeaddeaddeaddeaddeaddead",
"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": "0a02ea2a2208d43320ee5a8b677f40f0f6a8e780335212deaddeaddeaddeaddeaddeaddeaddeaddead5a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d2087090a2a5e78033",
"visible": false
}
},
"result": {
"signature": "b573db3a80dd15cfa8fbf2961a2d615ca0f62b4eb3b591bd0e3ac009dd31cc2461aeb9d31306c9e30f0afdcfa256bdfc03fed5fe01d441a5c867b2b142a9bbbe1B"
}
},
{
"name": "Note_too_long_string",
"parameters": {
"address_n": "m/44'/195'/0'/0/0",
"tx": {
"ref_block_bytes": "ea54",
"ref_block_hash": "e5ae03970dae489a",
"expiration": 1752563466000,
"timestamp": 1752563406000,
"data": "deade7fb3e7e39d4c650449e8d80c2731c4cc7fe0c7888a189a6eb1ead3621729a3ae8578299b2a1a35edf5ce3d9ae732cc4f202a34304900156ab37a78917609ae58dae01cb4de5ed98ff79a56e7f0e41f6042d3a734ae3b438209294a8a1899ddd4dee47c1cc86a0b2bf7d57d8457dfeed5fc2a24cd553c08a831f10a02ce5fb776d287e71e6a1a899ae966a0928f01ce6d3c4b0ee5151872c6dd80fefbfb79cff1949bfb5aba76b624e4c58eadf6c8ad97680e34d50807dc628dce44b39f3f405d5da406eb109cabdfc8c782be22f39c2e8814946e69977781fd66c691416b2785f41b508db37e819257751ee97794a57d7a8db5fb4b2cfce6031b76874922010"
},
"contract": {
"_message_type": "TronTransferContract",
"owner_address": "41f2cd810c48c401d392ead3c6e1e1cb9f57750a58",
"to_address": "4141f82674a30ae1328745d08afe2d1a0a24195283",
"amount": 18123456
},
"raw_data_hex": "0a02ea542208e5ae03970dae489a4090feb0e78033528202deade7fb3e7e39d4c650449e8d80c2731c4cc7fe0c7888a189a6eb1ead3621729a3ae8578299b2a1a35edf5ce3d9ae732cc4f202a34304900156ab37a78917609ae58dae01cb4de5ed98ff79a56e7f0e41f6042d3a734ae3b438209294a8a1899ddd4dee47c1cc86a0b2bf7d57d8457dfeed5fc2a24cd553c08a831f10a02ce5fb776d287e71e6a1a899ae966a0928f01ce6d3c4b0ee5151872c6dd80fefbfb79cff1949bfb5aba76b624e4c58eadf6c8ad97680e34d50807dc628dce44b39f3f405d5da406eb109cabdfc8c782be22f39c2e8814946e69977781fd66c691416b2785f41b508db37e819257751ee97794a57d7a8db5fb4b2cfce6031b768749220105a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d20870b0a9ade78033",
"raw": {
"txID": "cf8f946e3dc28d9f6076c7dbb5418c5996fce003b7bdca34a50b052200d7d575",
"raw_data": {
"data": "deade7fb3e7e39d4c650449e8d80c2731c4cc7fe0c7888a189a6eb1ead3621729a3ae8578299b2a1a35edf5ce3d9ae732cc4f202a34304900156ab37a78917609ae58dae01cb4de5ed98ff79a56e7f0e41f6042d3a734ae3b438209294a8a1899ddd4dee47c1cc86a0b2bf7d57d8457dfeed5fc2a24cd553c08a831f10a02ce5fb776d287e71e6a1a899ae966a0928f01ce6d3c4b0ee5151872c6dd80fefbfb79cff1949bfb5aba76b624e4c58eadf6c8ad97680e34d50807dc628dce44b39f3f405d5da406eb109cabdfc8c782be22f39c2e8814946e69977781fd66c691416b2785f41b508db37e819257751ee97794a57d7a8db5fb4b2cfce6031b76874922010",
"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": "0a02ea542208e5ae03970dae489a4090feb0e78033528202deade7fb3e7e39d4c650449e8d80c2731c4cc7fe0c7888a189a6eb1ead3621729a3ae8578299b2a1a35edf5ce3d9ae732cc4f202a34304900156ab37a78917609ae58dae01cb4de5ed98ff79a56e7f0e41f6042d3a734ae3b438209294a8a1899ddd4dee47c1cc86a0b2bf7d57d8457dfeed5fc2a24cd553c08a831f10a02ce5fb776d287e71e6a1a899ae966a0928f01ce6d3c4b0ee5151872c6dd80fefbfb79cff1949bfb5aba76b624e4c58eadf6c8ad97680e34d50807dc628dce44b39f3f405d5da406eb109cabdfc8c782be22f39c2e8814946e69977781fd66c691416b2785f41b508db37e819257751ee97794a57d7a8db5fb4b2cfce6031b768749220105a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a1541f2cd810c48c401d392ead3c6e1e1cb9f57750a5812154141f82674a30ae1328745d08afe2d1a0a2419528318c095d20870b0a9ade78033",
"visible": false
}
},
"result": {
"error_message": "Tron: data field too long"
}
}
]
}