From 327ccd38e4256781c82fbb3d0e9b120d9e08e7c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ioan=20Biz=C4=83u?= Date: Wed, 9 Jul 2025 15:12:48 +0200 Subject: [PATCH] Revert "feat: Make payment request protobuf fields optional." This reverts commit 4a4cc34d65ee5ec7b1cfc1617b2d20f15122ddf6. --- common/protob/messages-common.proto | 28 ++-- core/src/trezor/messages.py | 20 +-- python/src/trezorlib/messages.py | 44 +++--- .../src/protos/generated/messages_common.rs | 128 ++++++++++++------ .../src/protos/generated/messages_crypto.rs | 5 + 5 files changed, 141 insertions(+), 84 deletions(-) diff --git a/common/protob/messages-common.proto b/common/protob/messages-common.proto index c3ba9db955..33e7a377eb 100644 --- a/common/protob/messages-common.proto +++ b/common/protob/messages-common.proto @@ -182,11 +182,11 @@ message HDNodeType { message PaymentRequest { option (experimental_message) = true; - optional bytes nonce = 1; // the nonce used in the signature computation - optional string recipient_name = 2 [default=""]; // merchant's name - repeated PaymentRequestMemo memos = 3; // any memos that were signed as part of the request - optional uint64 amount = 4 [default=0]; // the sum of the external output amounts requested, required for non-CoinJoin - optional bytes signature = 5 [default=""]; // the trusted party's signature of the paymentRequestDigest + optional bytes nonce = 1; // the nonce used in the signature computation + required string recipient_name = 2; // merchant's name + repeated PaymentRequestMemo memos = 3; // any memos that were signed as part of the request + optional uint64 amount = 4; // the sum of the external output amounts requested, required for non-CoinJoin + required bytes signature = 5; // the trusted party's signature of the paymentRequestDigest message PaymentRequestMemo { optional TextMemo text_memo = 1; @@ -196,7 +196,7 @@ message PaymentRequest { } message TextMemo { - optional string text = 1 [default=""]; // plain-text note explaining the purpose of the payment request + required string text = 1; // plain-text note explaining the purpose of the payment request } message TextDetailsMemo { @@ -205,16 +205,16 @@ message PaymentRequest { } message RefundMemo { - optional string address = 1 [default=""]; // the address where the payment should be refunded if necessary - repeated uint32 address_n = 2; // BIP-32 path to derive the key from the master node - optional bytes mac = 3 [default=""]; // the MAC returned by GetAddress + required string address = 1; // the address where the payment should be refunded if necessary + 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 { - optional uint32 coin_type = 1 [default=0]; // the SLIP-0044 coin type of the address - optional string amount = 2 [default=""]; // the amount the address will receive as a human-readable string including units, e.g. "0.025 BTC" - optional string address = 3 [default=""]; // the address where the coin purchase will be delivered - repeated uint32 address_n = 4; // BIP-32 path to derive the key from the master node - optional bytes mac = 5 [default=""]; // the MAC returned by GetAddress + 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 + 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 e9e2d1aedb..6b66bf3bcd 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -251,17 +251,17 @@ if TYPE_CHECKING: nonce: "bytes | None" recipient_name: "str" memos: "list[PaymentRequestMemo]" - amount: "int" + amount: "int | None" signature: "bytes" def __init__( self, *, + recipient_name: "str", + signature: "bytes", memos: "list[PaymentRequestMemo] | None" = None, nonce: "bytes | None" = None, - recipient_name: "str | None" = None, amount: "int | None" = None, - signature: "bytes | None" = None, ) -> None: pass @@ -295,7 +295,7 @@ if TYPE_CHECKING: def __init__( self, *, - text: "str | None" = None, + text: "str", ) -> None: pass @@ -327,9 +327,9 @@ if TYPE_CHECKING: def __init__( self, *, + address: "str", + mac: "bytes", address_n: "list[int] | None" = None, - address: "str | None" = None, - mac: "bytes | None" = None, ) -> None: pass @@ -347,11 +347,11 @@ if TYPE_CHECKING: def __init__( self, *, + coin_type: "int", + amount: "str", + address: "str", + mac: "bytes", address_n: "list[int] | None" = None, - coin_type: "int | None" = None, - amount: "str | None" = None, - address: "str | None" = None, - mac: "bytes | None" = None, ) -> None: pass diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 5db19cd1be..0064cf7d96 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -886,26 +886,26 @@ class PaymentRequest(protobuf.MessageType): MESSAGE_WIRE_TYPE = 37 FIELDS = { 1: protobuf.Field("nonce", "bytes", repeated=False, required=False, default=None), - 2: protobuf.Field("recipient_name", "string", repeated=False, required=False, default=''), + 2: protobuf.Field("recipient_name", "string", repeated=False, required=True), 3: protobuf.Field("memos", "PaymentRequestMemo", repeated=True, required=False, default=None), - 4: protobuf.Field("amount", "uint64", repeated=False, required=False, default=0), - 5: protobuf.Field("signature", "bytes", repeated=False, required=False, default=b''), + 4: protobuf.Field("amount", "uint64", repeated=False, required=False, default=None), + 5: protobuf.Field("signature", "bytes", repeated=False, required=True), } def __init__( self, *, + recipient_name: "str", + signature: "bytes", memos: Optional[Sequence["PaymentRequestMemo"]] = None, nonce: Optional["bytes"] = None, - recipient_name: Optional["str"] = '', - amount: Optional["int"] = 0, - signature: Optional["bytes"] = b'', + amount: Optional["int"] = None, ) -> None: self.memos: Sequence["PaymentRequestMemo"] = memos if memos is not None else [] - self.nonce = nonce self.recipient_name = recipient_name - self.amount = amount self.signature = signature + self.nonce = nonce + self.amount = amount class PaymentRequestMemo(protobuf.MessageType): @@ -934,13 +934,13 @@ class PaymentRequestMemo(protobuf.MessageType): class TextMemo(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { - 1: protobuf.Field("text", "string", repeated=False, required=False, default=''), + 1: protobuf.Field("text", "string", repeated=False, required=True), } def __init__( self, *, - text: Optional["str"] = '', + text: "str", ) -> None: self.text = text @@ -965,17 +965,17 @@ class TextDetailsMemo(protobuf.MessageType): class RefundMemo(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { - 1: protobuf.Field("address", "string", repeated=False, required=False, default=''), + 1: protobuf.Field("address", "string", repeated=False, required=True), 2: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None), - 3: protobuf.Field("mac", "bytes", repeated=False, required=False, default=b''), + 3: protobuf.Field("mac", "bytes", repeated=False, required=True), } def __init__( self, *, + address: "str", + mac: "bytes", address_n: Optional[Sequence["int"]] = None, - address: Optional["str"] = '', - mac: Optional["bytes"] = b'', ) -> None: self.address_n: Sequence["int"] = address_n if address_n is not None else [] self.address = address @@ -985,21 +985,21 @@ class RefundMemo(protobuf.MessageType): class CoinPurchaseMemo(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { - 1: protobuf.Field("coin_type", "uint32", repeated=False, required=False, default=0), - 2: protobuf.Field("amount", "string", repeated=False, required=False, default=''), - 3: protobuf.Field("address", "string", repeated=False, required=False, default=''), + 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("address_n", "uint32", repeated=True, required=False, default=None), - 5: protobuf.Field("mac", "bytes", repeated=False, required=False, default=b''), + 5: protobuf.Field("mac", "bytes", repeated=False, required=True), } def __init__( self, *, + coin_type: "int", + amount: "str", + address: "str", + mac: "bytes", address_n: Optional[Sequence["int"]] = None, - coin_type: Optional["int"] = 0, - amount: Optional["str"] = '', - address: Optional["str"] = '', - mac: Optional["bytes"] = b'', ) -> None: self.address_n: Sequence["int"] = address_n if address_n is not None else [] self.coin_type = coin_type diff --git a/rust/trezor-client/src/protos/generated/messages_common.rs b/rust/trezor-client/src/protos/generated/messages_common.rs index ffc6b1362c..50db3b97b4 100644 --- a/rust/trezor-client/src/protos/generated/messages_common.rs +++ b/rust/trezor-client/src/protos/generated/messages_common.rs @@ -2567,7 +2567,7 @@ impl PaymentRequest { self.nonce.take().unwrap_or_else(|| ::std::vec::Vec::new()) } - // optional string recipient_name = 2; + // required string recipient_name = 2; pub fn recipient_name(&self) -> &str { match self.recipient_name.as_ref() { @@ -2606,7 +2606,7 @@ impl PaymentRequest { // optional uint64 amount = 4; pub fn amount(&self) -> u64 { - self.amount.unwrap_or(0u64) + self.amount.unwrap_or(0) } pub fn clear_amount(&mut self) { @@ -2622,12 +2622,12 @@ impl PaymentRequest { self.amount = ::std::option::Option::Some(v); } - // optional bytes signature = 5; + // required bytes signature = 5; pub fn signature(&self) -> &[u8] { match self.signature.as_ref() { Some(v) => v, - None => b"", + None => &[], } } @@ -2698,6 +2698,17 @@ impl ::protobuf::Message for PaymentRequest { const NAME: &'static str = "PaymentRequest"; fn is_initialized(&self) -> bool { + if self.recipient_name.is_none() { + return false; + } + if self.signature.is_none() { + return false; + } + for v in &self.memos { + if !v.is_initialized() { + return false; + } + }; true } @@ -2888,6 +2899,26 @@ pub mod payment_request { const NAME: &'static str = "PaymentRequestMemo"; fn is_initialized(&self) -> bool { + for v in &self.text_memo { + if !v.is_initialized() { + return false; + } + }; + for v in &self.refund_memo { + if !v.is_initialized() { + return false; + } + }; + for v in &self.coin_purchase_memo { + if !v.is_initialized() { + return false; + } + }; + for v in &self.text_details_memo { + if !v.is_initialized() { + return false; + } + }; true } @@ -3027,7 +3058,7 @@ pub mod payment_request { ::std::default::Default::default() } - // optional string text = 1; + // required string text = 1; pub fn text(&self) -> &str { match self.text.as_ref() { @@ -3083,6 +3114,9 @@ pub mod payment_request { const NAME: &'static str = "TextMemo"; fn is_initialized(&self) -> bool { + if self.text.is_none() { + return false; + } true } @@ -3401,7 +3435,7 @@ pub mod payment_request { ::std::default::Default::default() } - // optional string address = 1; + // required string address = 1; pub fn address(&self) -> &str { match self.address.as_ref() { @@ -3437,12 +3471,12 @@ pub mod payment_request { self.address.take().unwrap_or_else(|| ::std::string::String::new()) } - // optional bytes mac = 3; + // required bytes mac = 3; pub fn mac(&self) -> &[u8] { match self.mac.as_ref() { Some(v) => v, - None => b"", + None => &[], } } @@ -3503,6 +3537,12 @@ pub mod payment_request { const NAME: &'static str = "RefundMemo"; fn is_initialized(&self) -> bool { + if self.address.is_none() { + return false; + } + if self.mac.is_none() { + return false; + } true } @@ -3638,10 +3678,10 @@ pub mod payment_request { ::std::default::Default::default() } - // optional uint32 coin_type = 1; + // required uint32 coin_type = 1; pub fn coin_type(&self) -> u32 { - self.coin_type.unwrap_or(0u32) + self.coin_type.unwrap_or(0) } pub fn clear_coin_type(&mut self) { @@ -3657,7 +3697,7 @@ pub mod payment_request { self.coin_type = ::std::option::Option::Some(v); } - // optional string amount = 2; + // required string amount = 2; pub fn amount(&self) -> &str { match self.amount.as_ref() { @@ -3693,7 +3733,7 @@ pub mod payment_request { self.amount.take().unwrap_or_else(|| ::std::string::String::new()) } - // optional string address = 3; + // required string address = 3; pub fn address(&self) -> &str { match self.address.as_ref() { @@ -3729,12 +3769,12 @@ pub mod payment_request { self.address.take().unwrap_or_else(|| ::std::string::String::new()) } - // optional bytes mac = 5; + // required bytes mac = 5; pub fn mac(&self) -> &[u8] { match self.mac.as_ref() { Some(v) => v, - None => b"", + None => &[], } } @@ -3805,6 +3845,18 @@ pub mod payment_request { const NAME: &'static str = "CoinPurchaseMemo"; fn is_initialized(&self) -> bool { + if self.coin_type.is_none() { + return false; + } + if self.amount.is_none() { + return false; + } + if self.address.is_none() { + return false; + } + if self.mac.is_none() { + return false; + } true } @@ -3985,30 +4037,30 @@ static file_descriptor_proto_data: &'static [u8] = b"\ gerprint\x18\x02\x20\x02(\rR\x0bfingerprint\x12\x1b\n\tchild_num\x18\x03\ \x20\x02(\rR\x08childNum\x12\x1d\n\nchain_code\x18\x04\x20\x02(\x0cR\tch\ ainCode\x12\x1f\n\x0bprivate_key\x18\x05\x20\x01(\x0cR\nprivateKey\x12\ - \x1d\n\npublic_key\x18\x06\x20\x02(\x0cR\tpublicKey\"\xce\x07\n\x0ePayme\ - ntRequest\x12\x14\n\x05nonce\x18\x01\x20\x01(\x0cR\x05nonce\x12'\n\x0ere\ - cipient_name\x18\x02\x20\x01(\t:\0R\rrecipientName\x12R\n\x05memos\x18\ - \x03\x20\x03(\x0b2<.hw.trezor.messages.common.PaymentRequest.PaymentRequ\ - estMemoR\x05memos\x12\x19\n\x06amount\x18\x04\x20\x01(\x04:\x010R\x06amo\ - unt\x12\x1e\n\tsignature\x18\x05\x20\x01(\x0c:\0R\tsignature\x1a\x8d\x03\ - \n\x12PaymentRequestMemo\x12O\n\ttext_memo\x18\x01\x20\x01(\x0b22.hw.tre\ - zor.messages.common.PaymentRequest.TextMemoR\x08textMemo\x12U\n\x0brefun\ - d_memo\x18\x02\x20\x01(\x0b24.hw.trezor.messages.common.PaymentRequest.R\ - efundMemoR\nrefundMemo\x12h\n\x12coin_purchase_memo\x18\x03\x20\x01(\x0b\ - 2:.hw.trezor.messages.common.PaymentRequest.CoinPurchaseMemoR\x10coinPur\ - chaseMemo\x12e\n\x11text_details_memo\x18\x04\x20\x01(\x0b29.hw.trezor.m\ - essages.common.PaymentRequest.TextDetailsMemoR\x0ftextDetailsMemo\x1a\ - \x20\n\x08TextMemo\x12\x14\n\x04text\x18\x01\x20\x01(\t:\0R\x04text\x1a?\ - \n\x0fTextDetailsMemo\x12\x16\n\x05title\x18\x01\x20\x01(\t:\0R\x05title\ - \x12\x14\n\x04text\x18\x02\x20\x01(\t:\0R\x04text\x1aY\n\nRefundMemo\x12\ - \x1a\n\x07address\x18\x01\x20\x01(\t:\0R\x07address\x12\x1b\n\taddress_n\ - \x18\x02\x20\x03(\rR\x08addressN\x12\x12\n\x03mac\x18\x03\x20\x01(\x0c:\ - \0R\x03mac\x1a\x99\x01\n\x10CoinPurchaseMemo\x12\x1e\n\tcoin_type\x18\ - \x01\x20\x01(\r:\x010R\x08coinType\x12\x18\n\x06amount\x18\x02\x20\x01(\ - \t:\0R\x06amount\x12\x1a\n\x07address\x18\x03\x20\x01(\t:\0R\x07address\ - \x12\x1b\n\taddress_n\x18\x04\x20\x03(\rR\x08addressN\x12\x12\n\x03mac\ - \x18\x05\x20\x01(\x0c:\0R\x03mac:\x04\x88\xb2\x19\x01B>\n#com.satoshilab\ - s.trezor.lib.protobufB\x13TrezorMessageCommon\x80\xa6\x1d\x01\ + \x1d\n\npublic_key\x18\x06\x20\x02(\x0cR\tpublicKey\"\xb8\x07\n\x0ePayme\ + ntRequest\x12\x14\n\x05nonce\x18\x01\x20\x01(\x0cR\x05nonce\x12%\n\x0ere\ + cipient_name\x18\x02\x20\x02(\tR\rrecipientName\x12R\n\x05memos\x18\x03\ + \x20\x03(\x0b2<.hw.trezor.messages.common.PaymentRequest.PaymentRequestM\ + emoR\x05memos\x12\x16\n\x06amount\x18\x04\x20\x01(\x04R\x06amount\x12\ + \x1c\n\tsignature\x18\x05\x20\x02(\x0cR\tsignature\x1a\x8d\x03\n\x12Paym\ + entRequestMemo\x12O\n\ttext_memo\x18\x01\x20\x01(\x0b22.hw.trezor.messag\ + es.common.PaymentRequest.TextMemoR\x08textMemo\x12U\n\x0brefund_memo\x18\ + \x02\x20\x01(\x0b24.hw.trezor.messages.common.PaymentRequest.RefundMemoR\ + \nrefundMemo\x12h\n\x12coin_purchase_memo\x18\x03\x20\x01(\x0b2:.hw.trez\ + or.messages.common.PaymentRequest.CoinPurchaseMemoR\x10coinPurchaseMemo\ + \x12e\n\x11text_details_memo\x18\x04\x20\x01(\x0b29.hw.trezor.messages.c\ + ommon.PaymentRequest.TextDetailsMemoR\x0ftextDetailsMemo\x1a\x1e\n\x08Te\ + xtMemo\x12\x12\n\x04text\x18\x01\x20\x02(\tR\x04text\x1a?\n\x0fTextDetai\ + lsMemo\x12\x16\n\x05title\x18\x01\x20\x01(\t:\0R\x05title\x12\x14\n\x04t\ + ext\x18\x02\x20\x01(\t:\0R\x04text\x1aU\n\nRefundMemo\x12\x18\n\x07addre\ + ss\x18\x01\x20\x02(\tR\x07address\x12\x1b\n\taddress_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\x08c\ + oinType\x12\x16\n\x06amount\x18\x02\x20\x02(\tR\x06amount\x12\x18\n\x07a\ + ddress\x18\x03\x20\x02(\tR\x07address\x12\x1b\n\taddress_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.protobufB\x13TrezorMessa\ + geCommon\x80\xa6\x1d\x01\ "; /// `FileDescriptorProto` object which was a source for this generated file diff --git a/rust/trezor-client/src/protos/generated/messages_crypto.rs b/rust/trezor-client/src/protos/generated/messages_crypto.rs index 39cc4ddd01..18806cae6e 100644 --- a/rust/trezor-client/src/protos/generated/messages_crypto.rs +++ b/rust/trezor-client/src/protos/generated/messages_crypto.rs @@ -2064,6 +2064,11 @@ impl ::protobuf::Message for PaymentNotification { const NAME: &'static str = "PaymentNotification"; fn is_initialized(&self) -> bool { + for v in &self.payment_req { + if !v.is_initialized() { + return false; + } + }; true }