From 018d2c63d2e3a4aed62942d6d40f05e811020e52 Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Tue, 15 Apr 2025 14:56:14 +0200 Subject: [PATCH] feat: Make payment request protobuf fields optional. --- 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 ++++++------------ 4 files changed, 84 insertions(+), 136 deletions(-) diff --git a/common/protob/messages-common.proto b/common/protob/messages-common.proto index 1cee442f5a..081635026d 100644 --- a/common/protob/messages-common.proto +++ b/common/protob/messages-common.proto @@ -178,11 +178,11 @@ message HDNodeType { message PaymentRequest { option (experimental_message) = true; - 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 + 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 message PaymentRequestMemo { optional TextMemo text_memo = 1; @@ -192,7 +192,7 @@ message PaymentRequest { } message TextMemo { - required string text = 1; // plain-text note explaining the purpose of the payment request + optional string text = 1 [default=""]; // plain-text note explaining the purpose of the payment request } message TextDetailsMemo { @@ -201,16 +201,16 @@ message PaymentRequest { } message RefundMemo { - 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 + 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 } 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 - 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 + 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 } } diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 6fd3f14c90..b356d62a1f 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -460,17 +460,17 @@ if TYPE_CHECKING: nonce: "bytes | None" recipient_name: "str" memos: "list[PaymentRequestMemo]" - amount: "int | None" + amount: "int" 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 @@ -504,7 +504,7 @@ if TYPE_CHECKING: def __init__( self, *, - text: "str", + text: "str | None" = None, ) -> None: pass @@ -536,9 +536,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 @@ -556,11 +556,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 e5f3063bd3..1f081746eb 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -1102,26 +1102,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=True), + 2: protobuf.Field("recipient_name", "string", repeated=False, required=False, default=''), 3: protobuf.Field("memos", "PaymentRequestMemo", repeated=True, required=False, default=None), - 4: protobuf.Field("amount", "uint64", repeated=False, required=False, default=None), - 5: protobuf.Field("signature", "bytes", repeated=False, required=True), + 4: protobuf.Field("amount", "uint64", repeated=False, required=False, default=0), + 5: protobuf.Field("signature", "bytes", repeated=False, required=False, default=b''), } def __init__( self, *, - recipient_name: "str", - signature: "bytes", memos: Optional[Sequence["PaymentRequestMemo"]] = None, nonce: Optional["bytes"] = None, - amount: Optional["int"] = None, + recipient_name: Optional["str"] = '', + amount: Optional["int"] = 0, + signature: Optional["bytes"] = b'', ) -> None: self.memos: Sequence["PaymentRequestMemo"] = memos if memos is not None else [] - self.recipient_name = recipient_name - self.signature = signature self.nonce = nonce + self.recipient_name = recipient_name self.amount = amount + self.signature = signature class PaymentRequestMemo(protobuf.MessageType): @@ -1150,13 +1150,13 @@ class PaymentRequestMemo(protobuf.MessageType): class TextMemo(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { - 1: protobuf.Field("text", "string", repeated=False, required=True), + 1: protobuf.Field("text", "string", repeated=False, required=False, default=''), } def __init__( self, *, - text: "str", + text: Optional["str"] = '', ) -> None: self.text = text @@ -1181,17 +1181,17 @@ class TextDetailsMemo(protobuf.MessageType): class RefundMemo(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { - 1: protobuf.Field("address", "string", repeated=False, required=True), + 1: protobuf.Field("address", "string", repeated=False, required=False, default=''), 2: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None), - 3: protobuf.Field("mac", "bytes", repeated=False, required=True), + 3: protobuf.Field("mac", "bytes", repeated=False, required=False, default=b''), } 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 @@ -1201,21 +1201,21 @@ class RefundMemo(protobuf.MessageType): class CoinPurchaseMemo(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { - 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), + 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=''), 4: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None), - 5: protobuf.Field("mac", "bytes", repeated=False, required=True), + 5: protobuf.Field("mac", "bytes", repeated=False, required=False, default=b''), } 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 90068259e7..54e69d3511 100644 --- a/rust/trezor-client/src/protos/generated/messages_common.rs +++ b/rust/trezor-client/src/protos/generated/messages_common.rs @@ -2544,7 +2544,7 @@ impl PaymentRequest { self.nonce.take().unwrap_or_else(|| ::std::vec::Vec::new()) } - // required string recipient_name = 2; + // optional string recipient_name = 2; pub fn recipient_name(&self) -> &str { match self.recipient_name.as_ref() { @@ -2583,7 +2583,7 @@ impl PaymentRequest { // optional uint64 amount = 4; pub fn amount(&self) -> u64 { - self.amount.unwrap_or(0) + self.amount.unwrap_or(0u64) } pub fn clear_amount(&mut self) { @@ -2599,12 +2599,12 @@ impl PaymentRequest { self.amount = ::std::option::Option::Some(v); } - // required bytes signature = 5; + // optional bytes signature = 5; pub fn signature(&self) -> &[u8] { match self.signature.as_ref() { Some(v) => v, - None => &[], + None => b"", } } @@ -2675,17 +2675,6 @@ 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 } @@ -2876,26 +2865,6 @@ 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 } @@ -3035,7 +3004,7 @@ pub mod payment_request { ::std::default::Default::default() } - // required string text = 1; + // optional string text = 1; pub fn text(&self) -> &str { match self.text.as_ref() { @@ -3091,9 +3060,6 @@ pub mod payment_request { const NAME: &'static str = "TextMemo"; fn is_initialized(&self) -> bool { - if self.text.is_none() { - return false; - } true } @@ -3412,7 +3378,7 @@ pub mod payment_request { ::std::default::Default::default() } - // required string address = 1; + // optional string address = 1; pub fn address(&self) -> &str { match self.address.as_ref() { @@ -3448,12 +3414,12 @@ pub mod payment_request { self.address.take().unwrap_or_else(|| ::std::string::String::new()) } - // required bytes mac = 3; + // optional bytes mac = 3; pub fn mac(&self) -> &[u8] { match self.mac.as_ref() { Some(v) => v, - None => &[], + None => b"", } } @@ -3514,12 +3480,6 @@ 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 } @@ -3655,10 +3615,10 @@ pub mod payment_request { ::std::default::Default::default() } - // required uint32 coin_type = 1; + // optional uint32 coin_type = 1; pub fn coin_type(&self) -> u32 { - self.coin_type.unwrap_or(0) + self.coin_type.unwrap_or(0u32) } pub fn clear_coin_type(&mut self) { @@ -3674,7 +3634,7 @@ pub mod payment_request { self.coin_type = ::std::option::Option::Some(v); } - // required string amount = 2; + // optional string amount = 2; pub fn amount(&self) -> &str { match self.amount.as_ref() { @@ -3710,7 +3670,7 @@ pub mod payment_request { self.amount.take().unwrap_or_else(|| ::std::string::String::new()) } - // required string address = 3; + // optional string address = 3; pub fn address(&self) -> &str { match self.address.as_ref() { @@ -3746,12 +3706,12 @@ pub mod payment_request { self.address.take().unwrap_or_else(|| ::std::string::String::new()) } - // required bytes mac = 5; + // optional bytes mac = 5; pub fn mac(&self) -> &[u8] { match self.mac.as_ref() { Some(v) => v, - None => &[], + None => b"", } } @@ -3822,18 +3782,6 @@ 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 } @@ -4012,30 +3960,30 @@ 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\"\xb8\x07\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\ - \x16\n\x06amount\x18\x04\x20\x01(\x04R\x06amount\x12\x1c\n\tsignature\ - \x18\x05\x20\x02(\x0cR\tsignature\x1a\x8d\x03\n\x12PaymentRequestMemo\ - \x12O\n\ttext_memo\x18\x01\x20\x01(\x0b22.hw.trezor.messages.common.Paym\ - entRequest.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.trezor.messages.\ - common.PaymentRequest.CoinPurchaseMemoR\x10coinPurchaseMemo\x12e\n\x11te\ - xt_details_memo\x18\x04\x20\x01(\x0b29.hw.trezor.messages.common.Payment\ - Request.TextDetailsMemoR\x0ftextDetailsMemo\x1a\x1e\n\x08TextMemo\x12\ - \x12\n\x04text\x18\x01\x20\x02(\tR\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\x1aU\n\nRefundMemo\x12\x18\n\x07address\x18\ - \x01\x20\x02(\tR\x07address\x12\x1b\n\taddress_n\x18\x02\x20\x03(\rR\x08\ - addressN\x12\x10\n\x03mac\x18\x03\x20\x02(\x0cR\x03mac\x1a\x90\x01\n\x10\ - CoinPurchaseMemo\x12\x1b\n\tcoin_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\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\x13TrezorMessageCommon\ - \x80\xa6\x1d\x01\ + \x18\x06\x20\x02(\x0cR\tpublicKey\"\xce\x07\n\x0ePaymentRequest\x12\x14\ + \n\x05nonce\x18\x01\x20\x01(\x0cR\x05nonce\x12'\n\x0erecipient_name\x18\ + \x02\x20\x01(\t:\0R\rrecipientName\x12R\n\x05memos\x18\x03\x20\x03(\x0b2\ + <.hw.trezor.messages.common.PaymentRequest.PaymentRequestMemoR\x05memos\ + \x12\x19\n\x06amount\x18\x04\x20\x01(\x04:\x010R\x06amount\x12\x1e\n\tsi\ + gnature\x18\x05\x20\x01(\x0c:\0R\tsignature\x1a\x8d\x03\n\x12PaymentRequ\ + estMemo\x12O\n\ttext_memo\x18\x01\x20\x01(\x0b22.hw.trezor.messages.comm\ + on.PaymentRequest.TextMemoR\x08textMemo\x12U\n\x0brefund_memo\x18\x02\ + \x20\x01(\x0b24.hw.trezor.messages.common.PaymentRequest.RefundMemoR\nre\ + fundMemo\x12h\n\x12coin_purchase_memo\x18\x03\x20\x01(\x0b2:.hw.trezor.m\ + essages.common.PaymentRequest.CoinPurchaseMemoR\x10coinPurchaseMemo\x12e\ + \n\x11text_details_memo\x18\x04\x20\x01(\x0b29.hw.trezor.messages.common\ + .PaymentRequest.TextDetailsMemoR\x0ftextDetailsMemo\x1a\x20\n\x08TextMem\ + o\x12\x14\n\x04text\x18\x01\x20\x01(\t:\0R\x04text\x1a?\n\x0fTextDetails\ + Memo\x12\x16\n\x05title\x18\x01\x20\x01(\t:\0R\x05title\x12\x14\n\x04tex\ + t\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:\x010\ + R\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.satoshilabs.trezor.lib.protobufB\ + \x13TrezorMessageCommon\x80\xa6\x1d\x01\ "; /// `FileDescriptorProto` object which was a source for this generated file