From 83f447c42907c8220befc699856fe24d7f78e46f Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Mon, 14 Apr 2025 17:16:54 +0200 Subject: [PATCH] feat(common): Add address_n field to PaymentRequest memos. --- common/protob/messages-common.proto | 6 +- core/src/trezor/messages.py | 4 + python/src/trezorlib/messages.py | 10 ++- .../src/protos/generated/messages_common.rs | 77 +++++++++++++++---- 4 files changed, 76 insertions(+), 21 deletions(-) diff --git a/common/protob/messages-common.proto b/common/protob/messages-common.proto index affc7d77a0..3b9743956b 100644 --- a/common/protob/messages-common.proto +++ b/common/protob/messages-common.proto @@ -196,13 +196,15 @@ message PaymentRequest { message RefundMemo { required string address = 1; // the address where the payment should be refunded if necessary - required bytes mac = 2; // the MAC returned by GetAddress + repeated uint32 address_n = 2; // BIP-32 path to derive the key from the master node + required bytes mac = 3; // the MAC returned by GetAddress } message CoinPurchaseMemo { required uint32 coin_type = 1; // the SLIP-0044 coin type of the address required string amount = 2; // the amount the address will receive as a human-readable string including units, e.g. "0.025 BTC" required string address = 3; // the address where the coin purchase will be delivered - required bytes mac = 4; // the MAC returned by GetAddress + repeated uint32 address_n = 4; // BIP-32 path to derive the key from the master node + required bytes mac = 5; // the MAC returned by GetAddress } } diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index a8190672d6..a417194d3a 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -512,6 +512,7 @@ if TYPE_CHECKING: class RefundMemo(protobuf.MessageType): address: "str" + address_n: "list[int]" mac: "bytes" def __init__( @@ -519,6 +520,7 @@ if TYPE_CHECKING: *, address: "str", mac: "bytes", + address_n: "list[int] | None" = None, ) -> None: pass @@ -530,6 +532,7 @@ if TYPE_CHECKING: coin_type: "int" amount: "str" address: "str" + address_n: "list[int]" mac: "bytes" def __init__( @@ -539,6 +542,7 @@ if TYPE_CHECKING: amount: "str", address: "str", mac: "bytes", + address_n: "list[int] | None" = None, ) -> None: pass diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 1505d47101..ffe43ae29b 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -1162,7 +1162,8 @@ class RefundMemo(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { 1: protobuf.Field("address", "string", repeated=False, required=True), - 2: protobuf.Field("mac", "bytes", repeated=False, required=True), + 2: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None), + 3: protobuf.Field("mac", "bytes", repeated=False, required=True), } def __init__( @@ -1170,7 +1171,9 @@ class RefundMemo(protobuf.MessageType): *, address: "str", mac: "bytes", + address_n: Optional[Sequence["int"]] = None, ) -> None: + self.address_n: Sequence["int"] = address_n if address_n is not None else [] self.address = address self.mac = mac @@ -1181,7 +1184,8 @@ class CoinPurchaseMemo(protobuf.MessageType): 1: protobuf.Field("coin_type", "uint32", repeated=False, required=True), 2: protobuf.Field("amount", "string", repeated=False, required=True), 3: protobuf.Field("address", "string", repeated=False, required=True), - 4: protobuf.Field("mac", "bytes", repeated=False, required=True), + 4: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None), + 5: protobuf.Field("mac", "bytes", repeated=False, required=True), } def __init__( @@ -1191,7 +1195,9 @@ class CoinPurchaseMemo(protobuf.MessageType): amount: "str", address: "str", mac: "bytes", + address_n: Optional[Sequence["int"]] = None, ) -> None: + self.address_n: Sequence["int"] = address_n if address_n is not None else [] self.coin_type = coin_type self.amount = amount self.address = address diff --git a/rust/trezor-client/src/protos/generated/messages_common.rs b/rust/trezor-client/src/protos/generated/messages_common.rs index 4f3a883e32..076c2e59e9 100644 --- a/rust/trezor-client/src/protos/generated/messages_common.rs +++ b/rust/trezor-client/src/protos/generated/messages_common.rs @@ -3156,6 +3156,8 @@ pub mod payment_request { // message fields // @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.RefundMemo.address) pub address: ::std::option::Option<::std::string::String>, + // @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.RefundMemo.address_n) + pub address_n: ::std::vec::Vec, // @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.RefundMemo.mac) pub mac: ::std::option::Option<::std::vec::Vec>, // special fields @@ -3210,7 +3212,7 @@ pub mod payment_request { self.address.take().unwrap_or_else(|| ::std::string::String::new()) } - // required bytes mac = 2; + // required bytes mac = 3; pub fn mac(&self) -> &[u8] { match self.mac.as_ref() { @@ -3247,13 +3249,18 @@ pub mod payment_request { } pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(2); + 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::<_, _>( "address", |m: &RefundMemo| { &m.address }, |m: &mut RefundMemo| { &mut m.address }, )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "address_n", + |m: &RefundMemo| { &m.address_n }, + |m: &mut RefundMemo| { &mut m.address_n }, + )); fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( "mac", |m: &RefundMemo| { &m.mac }, @@ -3287,6 +3294,12 @@ pub mod payment_request { self.address = ::std::option::Option::Some(is.read_string()?); }, 18 => { + is.read_repeated_packed_uint32_into(&mut self.address_n)?; + }, + 16 => { + self.address_n.push(is.read_uint32()?); + }, + 26 => { self.mac = ::std::option::Option::Some(is.read_bytes()?); }, tag => { @@ -3304,8 +3317,11 @@ pub mod payment_request { if let Some(v) = self.address.as_ref() { my_size += ::protobuf::rt::string_size(1, &v); } + for value in &self.address_n { + my_size += ::protobuf::rt::uint32_size(2, *value); + }; if let Some(v) = self.mac.as_ref() { - my_size += ::protobuf::rt::bytes_size(2, &v); + my_size += ::protobuf::rt::bytes_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); @@ -3316,8 +3332,11 @@ pub mod payment_request { if let Some(v) = self.address.as_ref() { os.write_string(1, v)?; } + for v in &self.address_n { + os.write_uint32(2, *v)?; + }; if let Some(v) = self.mac.as_ref() { - os.write_bytes(2, v)?; + os.write_bytes(3, v)?; } os.write_unknown_fields(self.special_fields.unknown_fields())?; ::std::result::Result::Ok(()) @@ -3337,6 +3356,7 @@ pub mod payment_request { fn clear(&mut self) { self.address = ::std::option::Option::None; + self.address_n.clear(); self.mac = ::std::option::Option::None; self.special_fields.clear(); } @@ -3344,6 +3364,7 @@ pub mod payment_request { fn default_instance() -> &'static RefundMemo { static instance: RefundMemo = RefundMemo { address: ::std::option::Option::None, + address_n: ::std::vec::Vec::new(), mac: ::std::option::Option::None, special_fields: ::protobuf::SpecialFields::new(), }; @@ -3378,6 +3399,8 @@ pub mod payment_request { pub amount: ::std::option::Option<::std::string::String>, // @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.CoinPurchaseMemo.address) pub address: ::std::option::Option<::std::string::String>, + // @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.CoinPurchaseMemo.address_n) + pub address_n: ::std::vec::Vec, // @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.CoinPurchaseMemo.mac) pub mac: ::std::option::Option<::std::vec::Vec>, // special fields @@ -3487,7 +3510,7 @@ pub mod payment_request { self.address.take().unwrap_or_else(|| ::std::string::String::new()) } - // required bytes mac = 4; + // required bytes mac = 5; pub fn mac(&self) -> &[u8] { match self.mac.as_ref() { @@ -3524,7 +3547,7 @@ pub mod payment_request { } pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(4); + let mut fields = ::std::vec::Vec::with_capacity(5); let mut oneofs = ::std::vec::Vec::with_capacity(0); fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( "coin_type", @@ -3541,6 +3564,11 @@ pub mod payment_request { |m: &CoinPurchaseMemo| { &m.address }, |m: &mut CoinPurchaseMemo| { &mut m.address }, )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "address_n", + |m: &CoinPurchaseMemo| { &m.address_n }, + |m: &mut CoinPurchaseMemo| { &mut m.address_n }, + )); fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( "mac", |m: &CoinPurchaseMemo| { &m.mac }, @@ -3586,6 +3614,12 @@ pub mod payment_request { self.address = ::std::option::Option::Some(is.read_string()?); }, 34 => { + is.read_repeated_packed_uint32_into(&mut self.address_n)?; + }, + 32 => { + self.address_n.push(is.read_uint32()?); + }, + 42 => { self.mac = ::std::option::Option::Some(is.read_bytes()?); }, tag => { @@ -3609,8 +3643,11 @@ pub mod payment_request { if let Some(v) = self.address.as_ref() { my_size += ::protobuf::rt::string_size(3, &v); } + for value in &self.address_n { + my_size += ::protobuf::rt::uint32_size(4, *value); + }; if let Some(v) = self.mac.as_ref() { - my_size += ::protobuf::rt::bytes_size(4, &v); + my_size += ::protobuf::rt::bytes_size(5, &v); } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); self.special_fields.cached_size().set(my_size as u32); @@ -3627,8 +3664,11 @@ pub mod payment_request { if let Some(v) = self.address.as_ref() { os.write_string(3, v)?; } + for v in &self.address_n { + os.write_uint32(4, *v)?; + }; if let Some(v) = self.mac.as_ref() { - os.write_bytes(4, v)?; + os.write_bytes(5, v)?; } os.write_unknown_fields(self.special_fields.unknown_fields())?; ::std::result::Result::Ok(()) @@ -3650,6 +3690,7 @@ pub mod payment_request { self.coin_type = ::std::option::Option::None; self.amount = ::std::option::Option::None; self.address = ::std::option::Option::None; + self.address_n.clear(); self.mac = ::std::option::Option::None; self.special_fields.clear(); } @@ -3659,6 +3700,7 @@ pub mod payment_request { coin_type: ::std::option::Option::None, amount: ::std::option::Option::None, address: ::std::option::Option::None, + address_n: ::std::vec::Vec::new(), mac: ::std::option::Option::None, special_fields: ::protobuf::SpecialFields::new(), }; @@ -3734,7 +3776,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x02(\rR\x0bfingerprint\x12\x1b\n\tchild_num\x18\x03\x20\x02(\rR\x08chil\ dNum\x12\x1d\n\nchain_code\x18\x04\x20\x02(\x0cR\tchainCode\x12\x1f\n\ \x0bprivate_key\x18\x05\x20\x01(\x0cR\nprivateKey\x12\x1d\n\npublic_key\ - \x18\x06\x20\x02(\x0cR\tpublicKey\"\xd5\x05\n\x0ePaymentRequest\x12\x14\ + \x18\x06\x20\x02(\x0cR\tpublicKey\"\x90\x06\n\x0ePaymentRequest\x12\x14\ \n\x05nonce\x18\x01\x20\x01(\x0cR\x05nonce\x12%\n\x0erecipient_name\x18\ \x02\x20\x02(\tR\rrecipientName\x12R\n\x05memos\x18\x03\x20\x03(\x0b2<.h\ w.trezor.messages.common.PaymentRequest.PaymentRequestMemoR\x05memos\x12\ @@ -3745,14 +3787,15 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x0b24.hw.trezor.messages.common.PaymentRequest.RefundMemoR\nrefundMemo\ \x12h\n\x12coin_purchase_memo\x18\x03\x20\x01(\x0b2:.hw.trezor.messages.\ common.PaymentRequest.CoinPurchaseMemoR\x10coinPurchaseMemo\x1a\x1e\n\ - \x08TextMemo\x12\x12\n\x04text\x18\x01\x20\x02(\tR\x04text\x1a8\n\nRefun\ - dMemo\x12\x18\n\x07address\x18\x01\x20\x02(\tR\x07address\x12\x10\n\x03m\ - ac\x18\x02\x20\x02(\x0cR\x03mac\x1as\n\x10CoinPurchaseMemo\x12\x1b\n\tco\ - in_type\x18\x01\x20\x02(\rR\x08coinType\x12\x16\n\x06amount\x18\x02\x20\ - \x02(\tR\x06amount\x12\x18\n\x07address\x18\x03\x20\x02(\tR\x07address\ - \x12\x10\n\x03mac\x18\x04\x20\x02(\x0cR\x03mac:\x04\x88\xb2\x19\x01B>\n#\ - com.satoshilabs.trezor.lib.protobufB\x13TrezorMessageCommon\x80\xa6\x1d\ - \x01\ + \x08TextMemo\x12\x12\n\x04text\x18\x01\x20\x02(\tR\x04text\x1aU\n\nRefun\ + dMemo\x12\x18\n\x07address\x18\x01\x20\x02(\tR\x07address\x12\x1b\n\tadd\ + ress_n\x18\x02\x20\x03(\rR\x08addressN\x12\x10\n\x03mac\x18\x03\x20\x02(\ + \x0cR\x03mac\x1a\x90\x01\n\x10CoinPurchaseMemo\x12\x1b\n\tcoin_type\x18\ + \x01\x20\x02(\rR\x08coinType\x12\x16\n\x06amount\x18\x02\x20\x02(\tR\x06\ + amount\x12\x18\n\x07address\x18\x03\x20\x02(\tR\x07address\x12\x1b\n\tad\ + dress_n\x18\x04\x20\x03(\rR\x08addressN\x12\x10\n\x03mac\x18\x05\x20\x02\ + (\x0cR\x03mac:\x04\x88\xb2\x19\x01B>\n#com.satoshilabs.trezor.lib.protob\ + ufB\x13TrezorMessageCommon\x80\xa6\x1d\x01\ "; /// `FileDescriptorProto` object which was a source for this generated file