From bf45d51af64a192259a9a0a61abf7d1598294a48 Mon Sep 17 00:00:00 2001 From: gabrielkerekes Date: Wed, 18 Oct 2023 11:48:32 +0200 Subject: [PATCH] feat(solana): basic `sign_tx` setup and support --- common/protob/messages-solana.proto | 18 + common/protob/messages.proto | 2 + core/src/all_modules.py | 2 + core/src/apps/solana/sign_tx.py | 27 ++ core/src/apps/workflow_handlers.py | 2 + core/src/trezor/enums/MessageType.py | 2 + core/src/trezor/enums/__init__.py | 2 + core/src/trezor/messages.py | 30 ++ python/src/trezorlib/cli/solana.py | 14 + python/src/trezorlib/messages.py | 33 ++ python/src/trezorlib/solana.py | 14 + rust/trezor-client/src/messages/generated.rs | 2 + .../src/protos/generated/messages.rs | 60 +-- .../src/protos/generated/messages_solana.rs | 352 +++++++++++++++++- 14 files changed, 535 insertions(+), 25 deletions(-) create mode 100644 core/src/apps/solana/sign_tx.py diff --git a/common/protob/messages-solana.proto b/common/protob/messages-solana.proto index 5fa509225..6b35c1454 100644 --- a/common/protob/messages-solana.proto +++ b/common/protob/messages-solana.proto @@ -42,3 +42,21 @@ message SolanaAddress { required string address = 1; // Solana address as Base58 encoded string } +/** + * Request: Ask device to sign a Solana transaction + * @start + * @next SolanaTxSignature + * @next Failure + */ +message SolanaSignTx { + repeated uint32 address_n = 1; // BIP-32 path to derive the key to sign with + required bytes serialized_tx = 2; // serialized tx to be signed +} + +/** + * Response: Contains the transaction signature + * @end + */ +message SolanaTxSignature { + required bytes signature = 1; // tx signature +} diff --git a/common/protob/messages.proto b/common/protob/messages.proto index 91aef61c6..8ddce41d6 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -368,4 +368,6 @@ enum MessageType { MessageType_SolanaPublicKey = 901 [(wire_out) = true]; MessageType_SolanaGetAddress = 902 [(wire_in) = true]; MessageType_SolanaAddress = 903 [(wire_out) = true]; + MessageType_SolanaSignTx = 904 [(wire_in) = true]; + MessageType_SolanaTxSignature = 905 [(wire_out) = true]; } diff --git a/core/src/all_modules.py b/core/src/all_modules.py index 6779184d6..6be0c01cd 100644 --- a/core/src/all_modules.py +++ b/core/src/all_modules.py @@ -687,6 +687,8 @@ if not utils.BITCOIN_ONLY: import apps.solana.get_address apps.solana.get_public_key import apps.solana.get_public_key + apps.solana.sign_tx + import apps.solana.sign_tx apps.stellar import apps.stellar apps.stellar.consts diff --git a/core/src/apps/solana/sign_tx.py b/core/src/apps/solana/sign_tx.py new file mode 100644 index 000000000..9f022b2a0 --- /dev/null +++ b/core/src/apps/solana/sign_tx.py @@ -0,0 +1,27 @@ +from typing import TYPE_CHECKING + +from apps.common.keychain import with_slip44_keychain + +from . import CURVE, PATTERNS, SLIP44_ID + +if TYPE_CHECKING: + from trezor.messages import SolanaSignTx, SolanaTxSignature + + from apps.common.keychain import Keychain + + +@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE) +async def sign_tx( + msg: SolanaSignTx, + keychain: Keychain, +) -> SolanaTxSignature: + from trezor.crypto.curve import ed25519 + from trezor.messages import SolanaTxSignature + + address_n = msg.address_n + serialized_tx = msg.serialized_tx + + node = keychain.derive(address_n) + signature = ed25519.sign(node.private_key(), serialized_tx) + + return SolanaTxSignature(signature=signature) diff --git a/core/src/apps/workflow_handlers.py b/core/src/apps/workflow_handlers.py index 69b72638c..8b373c4c4 100644 --- a/core/src/apps/workflow_handlers.py +++ b/core/src/apps/workflow_handlers.py @@ -195,6 +195,8 @@ def _find_message_handler_module(msg_type: int) -> str: return "apps.solana.get_public_key" if msg_type == MessageType.SolanaGetAddress: return "apps.solana.get_address" + if msg_type == MessageType.SolanaSignTx: + return "apps.solana.sign_tx" raise ValueError diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index 0ea3565db..0dbc2cc1b 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -240,3 +240,5 @@ if not utils.BITCOIN_ONLY: SolanaPublicKey = 901 SolanaGetAddress = 902 SolanaAddress = 903 + SolanaSignTx = 904 + SolanaTxSignature = 905 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index bca4a8502..02ff1dda4 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -258,6 +258,8 @@ if TYPE_CHECKING: SolanaPublicKey = 901 SolanaGetAddress = 902 SolanaAddress = 903 + SolanaSignTx = 904 + SolanaTxSignature = 905 class FailureType(IntEnum): UnexpectedMessage = 1 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index b007187e9..b53ac64e0 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -5257,6 +5257,36 @@ if TYPE_CHECKING: def is_type_of(cls, msg: Any) -> TypeGuard["SolanaAddress"]: return isinstance(msg, cls) + class SolanaSignTx(protobuf.MessageType): + address_n: "list[int]" + serialized_tx: "bytes" + + def __init__( + self, + *, + serialized_tx: "bytes", + address_n: "list[int] | None" = None, + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["SolanaSignTx"]: + return isinstance(msg, cls) + + class SolanaTxSignature(protobuf.MessageType): + signature: "bytes" + + def __init__( + self, + *, + signature: "bytes", + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["SolanaTxSignature"]: + return isinstance(msg, cls) + class StellarAsset(protobuf.MessageType): type: "StellarAssetType" code: "str | None" diff --git a/python/src/trezorlib/cli/solana.py b/python/src/trezorlib/cli/solana.py index c33e94662..845e8ed98 100644 --- a/python/src/trezorlib/cli/solana.py +++ b/python/src/trezorlib/cli/solana.py @@ -45,3 +45,17 @@ def get_address( """Get Solana address.""" address_n = tools.parse_path(address) return solana.get_address(client, address_n, show_display, chunkify) + + +@cli.command() +@click.argument("serialized_tx", type=str) +@click.option("-n", "--address", default=DEFAULT_PATH, help=PATH_HELP) +@with_client +def sign_tx( + client: "TrezorClient", + address: str, + serialized_tx: str, +) -> messages.SolanaTxSignature: + """Sign Solana transaction.""" + address_n = tools.parse_path(address) + return solana.sign_tx(client, address_n, bytes.fromhex(serialized_tx)) diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 0d8999682..bafaeddca 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -266,6 +266,8 @@ class MessageType(IntEnum): SolanaPublicKey = 901 SolanaGetAddress = 902 SolanaAddress = 903 + SolanaSignTx = 904 + SolanaTxSignature = 905 class FailureType(IntEnum): @@ -6714,6 +6716,37 @@ class SolanaAddress(protobuf.MessageType): self.address = address +class SolanaSignTx(protobuf.MessageType): + MESSAGE_WIRE_TYPE = 904 + FIELDS = { + 1: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None), + 2: protobuf.Field("serialized_tx", "bytes", repeated=False, required=True), + } + + def __init__( + self, + *, + serialized_tx: "bytes", + address_n: Optional[Sequence["int"]] = None, + ) -> None: + self.address_n: Sequence["int"] = address_n if address_n is not None else [] + self.serialized_tx = serialized_tx + + +class SolanaTxSignature(protobuf.MessageType): + MESSAGE_WIRE_TYPE = 905 + FIELDS = { + 1: protobuf.Field("signature", "bytes", repeated=False, required=True), + } + + def __init__( + self, + *, + signature: "bytes", + ) -> None: + self.signature = signature + + class StellarAsset(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { diff --git a/python/src/trezorlib/solana.py b/python/src/trezorlib/solana.py index 7f3bda818..d2c20cf34 100644 --- a/python/src/trezorlib/solana.py +++ b/python/src/trezorlib/solana.py @@ -33,3 +33,17 @@ def get_address( chunkify=chunkify, ) ) + + +@expect(messages.SolanaTxSignature) +def sign_tx( + client: "TrezorClient", + address_n: List[int], + serialized_tx: bytes, +) -> "MessageType": + return client.call( + messages.SolanaSignTx( + address_n=address_n, + serialized_tx=serialized_tx, + ) + ) diff --git a/rust/trezor-client/src/messages/generated.rs b/rust/trezor-client/src/messages/generated.rs index d170fc946..e23118719 100644 --- a/rust/trezor-client/src/messages/generated.rs +++ b/rust/trezor-client/src/messages/generated.rs @@ -83,6 +83,8 @@ trezor_message_impl! { SolanaPublicKey => MessageType_SolanaPublicKey, SolanaGetAddress => MessageType_SolanaGetAddress, SolanaAddress => MessageType_SolanaAddress, + SolanaSignTx => MessageType_SolanaSignTx, + SolanaTxSignature => MessageType_SolanaTxSignature, } #[cfg(feature = "binance")] diff --git a/rust/trezor-client/src/protos/generated/messages.rs b/rust/trezor-client/src/protos/generated/messages.rs index 22e5f383b..798a103c4 100644 --- a/rust/trezor-client/src/protos/generated/messages.rs +++ b/rust/trezor-client/src/protos/generated/messages.rs @@ -502,6 +502,10 @@ pub enum MessageType { MessageType_SolanaGetAddress = 902, // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SolanaAddress) MessageType_SolanaAddress = 903, + // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SolanaSignTx) + MessageType_SolanaSignTx = 904, + // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SolanaTxSignature) + MessageType_SolanaTxSignature = 905, } impl ::protobuf::Enum for MessageType { @@ -750,6 +754,8 @@ impl ::protobuf::Enum for MessageType { 901 => ::std::option::Option::Some(MessageType::MessageType_SolanaPublicKey), 902 => ::std::option::Option::Some(MessageType::MessageType_SolanaGetAddress), 903 => ::std::option::Option::Some(MessageType::MessageType_SolanaAddress), + 904 => ::std::option::Option::Some(MessageType::MessageType_SolanaSignTx), + 905 => ::std::option::Option::Some(MessageType::MessageType_SolanaTxSignature), _ => ::std::option::Option::None } } @@ -993,6 +999,8 @@ impl ::protobuf::Enum for MessageType { "MessageType_SolanaPublicKey" => ::std::option::Option::Some(MessageType::MessageType_SolanaPublicKey), "MessageType_SolanaGetAddress" => ::std::option::Option::Some(MessageType::MessageType_SolanaGetAddress), "MessageType_SolanaAddress" => ::std::option::Option::Some(MessageType::MessageType_SolanaAddress), + "MessageType_SolanaSignTx" => ::std::option::Option::Some(MessageType::MessageType_SolanaSignTx), + "MessageType_SolanaTxSignature" => ::std::option::Option::Some(MessageType::MessageType_SolanaTxSignature), _ => ::std::option::Option::None } } @@ -1235,6 +1243,8 @@ impl ::protobuf::Enum for MessageType { MessageType::MessageType_SolanaPublicKey, MessageType::MessageType_SolanaGetAddress, MessageType::MessageType_SolanaAddress, + MessageType::MessageType_SolanaSignTx, + MessageType::MessageType_SolanaTxSignature, ]; } @@ -1483,6 +1493,8 @@ impl ::protobuf::EnumFull for MessageType { MessageType::MessageType_SolanaPublicKey => 234, MessageType::MessageType_SolanaGetAddress => 235, MessageType::MessageType_SolanaAddress => 236, + MessageType::MessageType_SolanaSignTx => 237, + MessageType::MessageType_SolanaTxSignature => 238, }; Self::enum_descriptor().value_by_index(index) } @@ -1532,7 +1544,7 @@ pub mod exts { static file_descriptor_proto_data: &'static [u8] = b"\ \n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\x20google/protobuf/de\ - scriptor.proto*\xf5Q\n\x0bMessageType\x12(\n\x16MessageType_Initialize\ + scriptor.proto*\xc4R\n\x0bMessageType\x12(\n\x16MessageType_Initialize\ \x10\0\x1a\x0c\x80\xa6\x1d\x01\xb0\xb5\x18\x01\x90\xb5\x18\x01\x12\x1e\n\ \x10MessageType_Ping\x10\x01\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12\ %\n\x13MessageType_Success\x10\x02\x1a\x0c\x80\xa6\x1d\x01\xa8\xb5\x18\ @@ -1800,28 +1812,30 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x1bMessageType_SolanaPublicKey\x10\x85\x07\x1a\x04\x98\xb5\x18\x01\x12'\ \n\x1cMessageType_SolanaGetAddress\x10\x86\x07\x1a\x04\x90\xb5\x18\x01\ \x12$\n\x19MessageType_SolanaAddress\x10\x87\x07\x1a\x04\x98\xb5\x18\x01\ - \x1a\x04\xc8\xf3\x18\x01\"\x04\x08Z\x10\\\"\x04\x08r\x10z\"\x06\x08\xac\ - \x02\x10\xb0\x02\"\x06\x08\xb5\x02\x10\xb8\x02:<\n\x07wire_in\x18\xd2\ - \x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x06wireIn:>\ - \n\x08wire_out\x18\xd3\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumVal\ - ueOptionsR\x07wireOut:G\n\rwire_debug_in\x18\xd4\x86\x03\x20\x01(\x08\ - \x12!.google.protobuf.EnumValueOptionsR\x0bwireDebugIn:I\n\x0ewire_debug\ - _out\x18\xd5\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\ - \x0cwireDebugOut:@\n\twire_tiny\x18\xd6\x86\x03\x20\x01(\x08\x12!.google\ - .protobuf.EnumValueOptionsR\x08wireTiny:L\n\x0fwire_bootloader\x18\xd7\ - \x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0ewireBoot\ - loader:C\n\x0bwire_no_fsm\x18\xd8\x86\x03\x20\x01(\x08\x12!.google.proto\ - buf.EnumValueOptionsR\twireNoFsm:F\n\x0cbitcoin_only\x18\xe0\xd4\x03\x20\ - \x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0bbitcoinOnly:U\n\x17h\ - as_bitcoin_only_values\x18\xb9\x8e\x03\x20\x01(\x08\x12\x1c.google.proto\ - buf.EnumOptionsR\x14hasBitcoinOnlyValues:T\n\x14experimental_message\x18\ - \xa1\x96\x03\x20\x01(\x08\x12\x1f.google.protobuf.MessageOptionsR\x13exp\ - erimentalMessage:>\n\twire_type\x18\xa2\x96\x03\x20\x01(\r\x12\x1f.googl\ - e.protobuf.MessageOptionsR\x08wireType:N\n\x12experimental_field\x18\x89\ - \x9e\x03\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\x11experimen\ - talField:U\n\x17include_in_bitcoin_only\x18\xe0\xd4\x03\x20\x01(\x08\x12\ - \x1c.google.protobuf.FileOptionsR\x14includeInBitcoinOnlyB8\n#com.satosh\ - ilabs.trezor.lib.protobufB\rTrezorMessage\x80\xa6\x1d\x01\ + \x12#\n\x18MessageType_SolanaSignTx\x10\x88\x07\x1a\x04\x90\xb5\x18\x01\ + \x12(\n\x1dMessageType_SolanaTxSignature\x10\x89\x07\x1a\x04\x98\xb5\x18\ + \x01\x1a\x04\xc8\xf3\x18\x01\"\x04\x08Z\x10\\\"\x04\x08r\x10z\"\x06\x08\ + \xac\x02\x10\xb0\x02\"\x06\x08\xb5\x02\x10\xb8\x02:<\n\x07wire_in\x18\ + \xd2\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x06wire\ + In:>\n\x08wire_out\x18\xd3\x86\x03\x20\x01(\x08\x12!.google.protobuf.Enu\ + mValueOptionsR\x07wireOut:G\n\rwire_debug_in\x18\xd4\x86\x03\x20\x01(\ + \x08\x12!.google.protobuf.EnumValueOptionsR\x0bwireDebugIn:I\n\x0ewire_d\ + ebug_out\x18\xd5\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOpti\ + onsR\x0cwireDebugOut:@\n\twire_tiny\x18\xd6\x86\x03\x20\x01(\x08\x12!.go\ + ogle.protobuf.EnumValueOptionsR\x08wireTiny:L\n\x0fwire_bootloader\x18\ + \xd7\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0ewire\ + Bootloader:C\n\x0bwire_no_fsm\x18\xd8\x86\x03\x20\x01(\x08\x12!.google.p\ + rotobuf.EnumValueOptionsR\twireNoFsm:F\n\x0cbitcoin_only\x18\xe0\xd4\x03\ + \x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0bbitcoinOnly:U\n\ + \x17has_bitcoin_only_values\x18\xb9\x8e\x03\x20\x01(\x08\x12\x1c.google.\ + protobuf.EnumOptionsR\x14hasBitcoinOnlyValues:T\n\x14experimental_messag\ + e\x18\xa1\x96\x03\x20\x01(\x08\x12\x1f.google.protobuf.MessageOptionsR\ + \x13experimentalMessage:>\n\twire_type\x18\xa2\x96\x03\x20\x01(\r\x12\ + \x1f.google.protobuf.MessageOptionsR\x08wireType:N\n\x12experimental_fie\ + ld\x18\x89\x9e\x03\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\ + \x11experimentalField:U\n\x17include_in_bitcoin_only\x18\xe0\xd4\x03\x20\ + \x01(\x08\x12\x1c.google.protobuf.FileOptionsR\x14includeInBitcoinOnlyB8\ + \n#com.satoshilabs.trezor.lib.protobufB\rTrezorMessage\x80\xa6\x1d\x01\ "; /// `FileDescriptorProto` object which was a source for this generated file diff --git a/rust/trezor-client/src/protos/generated/messages_solana.rs b/rust/trezor-client/src/protos/generated/messages_solana.rs index 73d1d4935..02691ba58 100644 --- a/rust/trezor-client/src/protos/generated/messages_solana.rs +++ b/rust/trezor-client/src/protos/generated/messages_solana.rs @@ -708,6 +708,349 @@ impl ::protobuf::reflect::ProtobufValue for SolanaAddress { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +// @@protoc_insertion_point(message:hw.trezor.messages.solana.SolanaSignTx) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct SolanaSignTx { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaSignTx.address_n) + pub address_n: ::std::vec::Vec, + // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaSignTx.serialized_tx) + pub serialized_tx: ::std::option::Option<::std::vec::Vec>, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaSignTx.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a SolanaSignTx { + fn default() -> &'a SolanaSignTx { + ::default_instance() + } +} + +impl SolanaSignTx { + pub fn new() -> SolanaSignTx { + ::std::default::Default::default() + } + + // required bytes serialized_tx = 2; + + pub fn serialized_tx(&self) -> &[u8] { + match self.serialized_tx.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_serialized_tx(&mut self) { + self.serialized_tx = ::std::option::Option::None; + } + + pub fn has_serialized_tx(&self) -> bool { + self.serialized_tx.is_some() + } + + // Param is passed by value, moved + pub fn set_serialized_tx(&mut self, v: ::std::vec::Vec) { + self.serialized_tx = ::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_serialized_tx(&mut self) -> &mut ::std::vec::Vec { + if self.serialized_tx.is_none() { + self.serialized_tx = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.serialized_tx.as_mut().unwrap() + } + + // Take field + pub fn take_serialized_tx(&mut self) -> ::std::vec::Vec { + self.serialized_tx.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + 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_vec_simpler_accessor::<_, _>( + "address_n", + |m: &SolanaSignTx| { &m.address_n }, + |m: &mut SolanaSignTx| { &mut m.address_n }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "serialized_tx", + |m: &SolanaSignTx| { &m.serialized_tx }, + |m: &mut SolanaSignTx| { &mut m.serialized_tx }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "SolanaSignTx", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for SolanaSignTx { + const NAME: &'static str = "SolanaSignTx"; + + fn is_initialized(&self) -> bool { + if self.serialized_tx.is_none() { + return false; + } + 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 => { + is.read_repeated_packed_uint32_into(&mut self.address_n)?; + }, + 8 => { + self.address_n.push(is.read_uint32()?); + }, + 18 => { + self.serialized_tx = ::std::option::Option::Some(is.read_bytes()?); + }, + 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; + for value in &self.address_n { + my_size += ::protobuf::rt::uint32_size(1, *value); + }; + if let Some(v) = self.serialized_tx.as_ref() { + my_size += ::protobuf::rt::bytes_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<()> { + for v in &self.address_n { + os.write_uint32(1, *v)?; + }; + if let Some(v) = self.serialized_tx.as_ref() { + os.write_bytes(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() -> SolanaSignTx { + SolanaSignTx::new() + } + + fn clear(&mut self) { + self.address_n.clear(); + self.serialized_tx = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static SolanaSignTx { + static instance: SolanaSignTx = SolanaSignTx { + address_n: ::std::vec::Vec::new(), + serialized_tx: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for SolanaSignTx { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("SolanaSignTx").unwrap()).clone() + } +} + +impl ::std::fmt::Display for SolanaSignTx { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SolanaSignTx { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.solana.SolanaTxSignature) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct SolanaTxSignature { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaTxSignature.signature) + pub signature: ::std::option::Option<::std::vec::Vec>, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaTxSignature.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a SolanaTxSignature { + fn default() -> &'a SolanaTxSignature { + ::default_instance() + } +} + +impl SolanaTxSignature { + pub fn new() -> SolanaTxSignature { + ::std::default::Default::default() + } + + // required bytes signature = 1; + + pub fn signature(&self) -> &[u8] { + match self.signature.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_signature(&mut self) { + self.signature = ::std::option::Option::None; + } + + pub fn has_signature(&self) -> bool { + self.signature.is_some() + } + + // Param is passed by value, moved + pub fn set_signature(&mut self, v: ::std::vec::Vec) { + self.signature = ::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_signature(&mut self) -> &mut ::std::vec::Vec { + if self.signature.is_none() { + self.signature = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.signature.as_mut().unwrap() + } + + // Take field + pub fn take_signature(&mut self) -> ::std::vec::Vec { + self.signature.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "signature", + |m: &SolanaTxSignature| { &m.signature }, + |m: &mut SolanaTxSignature| { &mut m.signature }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "SolanaTxSignature", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for SolanaTxSignature { + const NAME: &'static str = "SolanaTxSignature"; + + fn is_initialized(&self) -> bool { + if self.signature.is_none() { + return false; + } + 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.signature = ::std::option::Option::Some(is.read_bytes()?); + }, + 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.signature.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &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.signature.as_ref() { + os.write_bytes(1, 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() -> SolanaTxSignature { + SolanaTxSignature::new() + } + + fn clear(&mut self) { + self.signature = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static SolanaTxSignature { + static instance: SolanaTxSignature = SolanaTxSignature { + signature: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for SolanaTxSignature { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("SolanaTxSignature").unwrap()).clone() + } +} + +impl ::std::fmt::Display for SolanaTxSignature { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SolanaTxSignature { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + static file_descriptor_proto_data: &'static [u8] = b"\ \n\x15messages-solana.proto\x12\x19hw.trezor.messages.solana\x1a\x15mess\ ages-common.proto\"T\n\x12SolanaGetPublicKey\x12\x1b\n\taddress_n\x18\ @@ -717,7 +1060,10 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\x01\x20\x03(\rR\x08addressN\x12!\n\x0cshow_display\x18\x02\x20\x01(\ \x08R\x0bshowDisplay\x12\x1a\n\x08chunkify\x18\x03\x20\x01(\x08R\x08chun\ kify\")\n\rSolanaAddress\x12\x18\n\x07address\x18\x01\x20\x02(\tR\x07add\ - ress\ + ress\"P\n\x0cSolanaSignTx\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08ad\ + dressN\x12#\n\rserialized_tx\x18\x02\x20\x02(\x0cR\x0cserializedTx\"1\n\ + \x11SolanaTxSignature\x12\x1c\n\tsignature\x18\x01\x20\x02(\x0cR\tsignat\ + ure\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -736,11 +1082,13 @@ 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::messages_common::file_descriptor().clone()); - let mut messages = ::std::vec::Vec::with_capacity(4); + let mut messages = ::std::vec::Vec::with_capacity(6); messages.push(SolanaGetPublicKey::generated_message_descriptor_data()); messages.push(SolanaPublicKey::generated_message_descriptor_data()); messages.push(SolanaGetAddress::generated_message_descriptor_data()); messages.push(SolanaAddress::generated_message_descriptor_data()); + messages.push(SolanaSignTx::generated_message_descriptor_data()); + messages.push(SolanaTxSignature::generated_message_descriptor_data()); let mut enums = ::std::vec::Vec::with_capacity(0); ::protobuf::reflect::GeneratedFileDescriptor::new_generated( file_descriptor_proto(),