mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-21 09:39:02 +00:00
feat: Add "text details" memo to payment requests.
This commit is contained in:
parent
d156a629fa
commit
9e478e9b46
@ -188,12 +188,18 @@ message PaymentRequest {
|
||||
optional TextMemo text_memo = 1;
|
||||
optional RefundMemo refund_memo = 2;
|
||||
optional CoinPurchaseMemo coin_purchase_memo = 3;
|
||||
optional TextDetailsMemo text_details_memo = 4;
|
||||
}
|
||||
|
||||
message TextMemo {
|
||||
required string text = 1; // plain-text note explaining the purpose of the payment request
|
||||
}
|
||||
|
||||
message TextDetailsMemo {
|
||||
optional string title = 1 [default=""]; // plain-text heading
|
||||
optional string text = 2 [default=""]; // plain-text note containing additional details about the payment
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -13,6 +13,7 @@ if TYPE_CHECKING:
|
||||
_MEMO_TYPE_TEXT = const(1)
|
||||
_MEMO_TYPE_REFUND = const(2)
|
||||
_MEMO_TYPE_COIN_PURCHASE = const(3)
|
||||
_MEMO_TYPE_TEXT_DETAILS = const(4)
|
||||
|
||||
|
||||
class PaymentRequestVerifier:
|
||||
@ -73,6 +74,13 @@ class PaymentRequestVerifier:
|
||||
writers.write_uint32_le(self.h_pr, memo.coin_type)
|
||||
writers.write_bytes_prefixed(self.h_pr, memo.amount.encode())
|
||||
writers.write_bytes_prefixed(self.h_pr, memo.address.encode())
|
||||
elif m.text_details_memo is not None:
|
||||
memo = m.text_details_memo
|
||||
writers.write_uint32_le(self.h_pr, _MEMO_TYPE_TEXT_DETAILS)
|
||||
writers.write_bytes_prefixed(self.h_pr, memo.title.encode())
|
||||
writers.write_bytes_prefixed(self.h_pr, memo.text.encode())
|
||||
else:
|
||||
DataError("Unrecognized memo type in payment request.")
|
||||
|
||||
writers.write_uint32_le(self.h_pr, slip44_id)
|
||||
|
||||
|
18
core/src/trezor/messages.py
generated
18
core/src/trezor/messages.py
generated
@ -482,6 +482,7 @@ if TYPE_CHECKING:
|
||||
text_memo: "TextMemo | None"
|
||||
refund_memo: "RefundMemo | None"
|
||||
coin_purchase_memo: "CoinPurchaseMemo | None"
|
||||
text_details_memo: "TextDetailsMemo | None"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -489,6 +490,7 @@ if TYPE_CHECKING:
|
||||
text_memo: "TextMemo | None" = None,
|
||||
refund_memo: "RefundMemo | None" = None,
|
||||
coin_purchase_memo: "CoinPurchaseMemo | None" = None,
|
||||
text_details_memo: "TextDetailsMemo | None" = None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
@ -510,6 +512,22 @@ if TYPE_CHECKING:
|
||||
def is_type_of(cls, msg: Any) -> TypeGuard["TextMemo"]:
|
||||
return isinstance(msg, cls)
|
||||
|
||||
class TextDetailsMemo(protobuf.MessageType):
|
||||
title: "str"
|
||||
text: "str"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
title: "str | None" = None,
|
||||
text: "str | None" = None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, msg: Any) -> TypeGuard["TextDetailsMemo"]:
|
||||
return isinstance(msg, cls)
|
||||
|
||||
class RefundMemo(protobuf.MessageType):
|
||||
address: "str"
|
||||
address_n: "list[int]"
|
||||
|
20
python/src/trezorlib/messages.py
generated
20
python/src/trezorlib/messages.py
generated
@ -1130,6 +1130,7 @@ class PaymentRequestMemo(protobuf.MessageType):
|
||||
1: protobuf.Field("text_memo", "TextMemo", repeated=False, required=False, default=None),
|
||||
2: protobuf.Field("refund_memo", "RefundMemo", repeated=False, required=False, default=None),
|
||||
3: protobuf.Field("coin_purchase_memo", "CoinPurchaseMemo", repeated=False, required=False, default=None),
|
||||
4: protobuf.Field("text_details_memo", "TextDetailsMemo", repeated=False, required=False, default=None),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
@ -1138,10 +1139,12 @@ class PaymentRequestMemo(protobuf.MessageType):
|
||||
text_memo: Optional["TextMemo"] = None,
|
||||
refund_memo: Optional["RefundMemo"] = None,
|
||||
coin_purchase_memo: Optional["CoinPurchaseMemo"] = None,
|
||||
text_details_memo: Optional["TextDetailsMemo"] = None,
|
||||
) -> None:
|
||||
self.text_memo = text_memo
|
||||
self.refund_memo = refund_memo
|
||||
self.coin_purchase_memo = coin_purchase_memo
|
||||
self.text_details_memo = text_details_memo
|
||||
|
||||
|
||||
class TextMemo(protobuf.MessageType):
|
||||
@ -1158,6 +1161,23 @@ class TextMemo(protobuf.MessageType):
|
||||
self.text = text
|
||||
|
||||
|
||||
class TextDetailsMemo(protobuf.MessageType):
|
||||
MESSAGE_WIRE_TYPE = None
|
||||
FIELDS = {
|
||||
1: protobuf.Field("title", "string", repeated=False, required=False, default=''),
|
||||
2: protobuf.Field("text", "string", repeated=False, required=False, default=''),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
title: Optional["str"] = '',
|
||||
text: Optional["str"] = '',
|
||||
) -> None:
|
||||
self.title = title
|
||||
self.text = text
|
||||
|
||||
|
||||
class RefundMemo(protobuf.MessageType):
|
||||
MESSAGE_WIRE_TYPE = None
|
||||
FIELDS = {
|
||||
|
@ -2823,6 +2823,8 @@ pub mod payment_request {
|
||||
pub refund_memo: ::protobuf::MessageField<RefundMemo>,
|
||||
// @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.PaymentRequestMemo.coin_purchase_memo)
|
||||
pub coin_purchase_memo: ::protobuf::MessageField<CoinPurchaseMemo>,
|
||||
// @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.PaymentRequestMemo.text_details_memo)
|
||||
pub text_details_memo: ::protobuf::MessageField<TextDetailsMemo>,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:hw.trezor.messages.common.PaymentRequest.PaymentRequestMemo.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
@ -2840,7 +2842,7 @@ pub mod payment_request {
|
||||
}
|
||||
|
||||
pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||
let mut fields = ::std::vec::Vec::with_capacity(3);
|
||||
let mut fields = ::std::vec::Vec::with_capacity(4);
|
||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||
fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, TextMemo>(
|
||||
"text_memo",
|
||||
@ -2857,6 +2859,11 @@ pub mod payment_request {
|
||||
|m: &PaymentRequestMemo| { &m.coin_purchase_memo },
|
||||
|m: &mut PaymentRequestMemo| { &mut m.coin_purchase_memo },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, TextDetailsMemo>(
|
||||
"text_details_memo",
|
||||
|m: &PaymentRequestMemo| { &m.text_details_memo },
|
||||
|m: &mut PaymentRequestMemo| { &mut m.text_details_memo },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<PaymentRequestMemo>(
|
||||
"PaymentRequest.PaymentRequestMemo",
|
||||
fields,
|
||||
@ -2884,6 +2891,11 @@ pub mod payment_request {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
for v in &self.text_details_memo {
|
||||
if !v.is_initialized() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
true
|
||||
}
|
||||
|
||||
@ -2899,6 +2911,9 @@ pub mod payment_request {
|
||||
26 => {
|
||||
::protobuf::rt::read_singular_message_into_field(is, &mut self.coin_purchase_memo)?;
|
||||
},
|
||||
34 => {
|
||||
::protobuf::rt::read_singular_message_into_field(is, &mut self.text_details_memo)?;
|
||||
},
|
||||
tag => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||
},
|
||||
@ -2923,6 +2938,10 @@ pub mod payment_request {
|
||||
let len = v.compute_size();
|
||||
my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
|
||||
}
|
||||
if let Some(v) = self.text_details_memo.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
|
||||
@ -2938,6 +2957,9 @@ pub mod payment_request {
|
||||
if let Some(v) = self.coin_purchase_memo.as_ref() {
|
||||
::protobuf::rt::write_message_field_with_cached_size(3, v, os)?;
|
||||
}
|
||||
if let Some(v) = self.text_details_memo.as_ref() {
|
||||
::protobuf::rt::write_message_field_with_cached_size(4, v, os)?;
|
||||
}
|
||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
@ -2958,6 +2980,7 @@ pub mod payment_request {
|
||||
self.text_memo.clear();
|
||||
self.refund_memo.clear();
|
||||
self.coin_purchase_memo.clear();
|
||||
self.text_details_memo.clear();
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
@ -2966,6 +2989,7 @@ pub mod payment_request {
|
||||
text_memo: ::protobuf::MessageField::none(),
|
||||
refund_memo: ::protobuf::MessageField::none(),
|
||||
coin_purchase_memo: ::protobuf::MessageField::none(),
|
||||
text_details_memo: ::protobuf::MessageField::none(),
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
@ -3150,6 +3174,218 @@ pub mod payment_request {
|
||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(message:hw.trezor.messages.common.PaymentRequest.TextDetailsMemo)
|
||||
#[derive(PartialEq,Clone,Default,Debug)]
|
||||
pub struct TextDetailsMemo {
|
||||
// message fields
|
||||
// @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.TextDetailsMemo.title)
|
||||
pub title: ::std::option::Option<::std::string::String>,
|
||||
// @@protoc_insertion_point(field:hw.trezor.messages.common.PaymentRequest.TextDetailsMemo.text)
|
||||
pub text: ::std::option::Option<::std::string::String>,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:hw.trezor.messages.common.PaymentRequest.TextDetailsMemo.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a TextDetailsMemo {
|
||||
fn default() -> &'a TextDetailsMemo {
|
||||
<TextDetailsMemo as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl TextDetailsMemo {
|
||||
pub fn new() -> TextDetailsMemo {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// optional string title = 1;
|
||||
|
||||
pub fn title(&self) -> &str {
|
||||
match self.title.as_ref() {
|
||||
Some(v) => v,
|
||||
None => "",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_title(&mut self) {
|
||||
self.title = ::std::option::Option::None;
|
||||
}
|
||||
|
||||
pub fn has_title(&self) -> bool {
|
||||
self.title.is_some()
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_title(&mut self, v: ::std::string::String) {
|
||||
self.title = ::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_title(&mut self) -> &mut ::std::string::String {
|
||||
if self.title.is_none() {
|
||||
self.title = ::std::option::Option::Some(::std::string::String::new());
|
||||
}
|
||||
self.title.as_mut().unwrap()
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_title(&mut self) -> ::std::string::String {
|
||||
self.title.take().unwrap_or_else(|| ::std::string::String::new())
|
||||
}
|
||||
|
||||
// optional string text = 2;
|
||||
|
||||
pub fn text(&self) -> &str {
|
||||
match self.text.as_ref() {
|
||||
Some(v) => v,
|
||||
None => "",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_text(&mut self) {
|
||||
self.text = ::std::option::Option::None;
|
||||
}
|
||||
|
||||
pub fn has_text(&self) -> bool {
|
||||
self.text.is_some()
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_text(&mut self, v: ::std::string::String) {
|
||||
self.text = ::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_text(&mut self) -> &mut ::std::string::String {
|
||||
if self.text.is_none() {
|
||||
self.text = ::std::option::Option::Some(::std::string::String::new());
|
||||
}
|
||||
self.text.as_mut().unwrap()
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_text(&mut self) -> ::std::string::String {
|
||||
self.text.take().unwrap_or_else(|| ::std::string::String::new())
|
||||
}
|
||||
|
||||
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::<_, _>(
|
||||
"title",
|
||||
|m: &TextDetailsMemo| { &m.title },
|
||||
|m: &mut TextDetailsMemo| { &mut m.title },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
||||
"text",
|
||||
|m: &TextDetailsMemo| { &m.text },
|
||||
|m: &mut TextDetailsMemo| { &mut m.text },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<TextDetailsMemo>(
|
||||
"PaymentRequest.TextDetailsMemo",
|
||||
fields,
|
||||
oneofs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for TextDetailsMemo {
|
||||
const NAME: &'static str = "TextDetailsMemo";
|
||||
|
||||
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 {
|
||||
10 => {
|
||||
self.title = ::std::option::Option::Some(is.read_string()?);
|
||||
},
|
||||
18 => {
|
||||
self.text = ::std::option::Option::Some(is.read_string()?);
|
||||
},
|
||||
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.title.as_ref() {
|
||||
my_size += ::protobuf::rt::string_size(1, &v);
|
||||
}
|
||||
if let Some(v) = self.text.as_ref() {
|
||||
my_size += ::protobuf::rt::string_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.title.as_ref() {
|
||||
os.write_string(1, v)?;
|
||||
}
|
||||
if let Some(v) = self.text.as_ref() {
|
||||
os.write_string(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() -> TextDetailsMemo {
|
||||
TextDetailsMemo::new()
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.title = ::std::option::Option::None;
|
||||
self.text = ::std::option::Option::None;
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static TextDetailsMemo {
|
||||
static instance: TextDetailsMemo = TextDetailsMemo {
|
||||
title: ::std::option::Option::None,
|
||||
text: ::std::option::Option::None,
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::MessageFull for TextDetailsMemo {
|
||||
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("PaymentRequest.TextDetailsMemo").unwrap()).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for TextDetailsMemo {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for TextDetailsMemo {
|
||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(message:hw.trezor.messages.common.PaymentRequest.RefundMemo)
|
||||
#[derive(PartialEq,Clone,Default,Debug)]
|
||||
pub struct RefundMemo {
|
||||
@ -3776,26 +4012,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\"\x90\x06\n\x0ePaymentRequest\x12\x14\
|
||||
\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\xa6\x02\n\x12PaymentRequestMemo\
|
||||
\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\x1a\x1e\n\
|
||||
\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\
|
||||
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\
|
||||
";
|
||||
|
||||
/// `FileDescriptorProto` object which was a source for this generated file
|
||||
@ -3814,7 +4054,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
|
||||
let generated_file_descriptor = generated_file_descriptor_lazy.get(|| {
|
||||
let mut deps = ::std::vec::Vec::with_capacity(1);
|
||||
deps.push(super::options::file_descriptor().clone());
|
||||
let mut messages = ::std::vec::Vec::with_capacity(16);
|
||||
let mut messages = ::std::vec::Vec::with_capacity(17);
|
||||
messages.push(Success::generated_message_descriptor_data());
|
||||
messages.push(Failure::generated_message_descriptor_data());
|
||||
messages.push(ButtonRequest::generated_message_descriptor_data());
|
||||
@ -3829,6 +4069,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
|
||||
messages.push(PaymentRequest::generated_message_descriptor_data());
|
||||
messages.push(payment_request::PaymentRequestMemo::generated_message_descriptor_data());
|
||||
messages.push(payment_request::TextMemo::generated_message_descriptor_data());
|
||||
messages.push(payment_request::TextDetailsMemo::generated_message_descriptor_data());
|
||||
messages.push(payment_request::RefundMemo::generated_message_descriptor_data());
|
||||
messages.push(payment_request::CoinPurchaseMemo::generated_message_descriptor_data());
|
||||
let mut enums = ::std::vec::Vec::with_capacity(3);
|
||||
|
@ -13,6 +13,12 @@ class TextMemo:
|
||||
text: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class TextDetailsMemo:
|
||||
title: str
|
||||
text: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class RefundMemo:
|
||||
address_n: list[int]
|
||||
@ -94,6 +100,13 @@ def make_payment_request(
|
||||
h_pr.update(memo.slip44.to_bytes(4, "little"))
|
||||
hash_bytes_prefixed(h_pr, memo.amount.encode())
|
||||
hash_bytes_prefixed(h_pr, memo.address_resp.address.encode())
|
||||
elif isinstance(memo, TextDetailsMemo):
|
||||
msg_memo = messages.TextDetailsMemo(text=memo.text)
|
||||
msg_memos.append(messages.PaymentRequestMemo(text_memo=msg_memo))
|
||||
memo_type = 4
|
||||
h_pr.update(memo_type.to_bytes(4, "little"))
|
||||
hash_bytes_prefixed(h_pr, memo.title.encode())
|
||||
hash_bytes_prefixed(h_pr, memo.text.encode())
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user