DOCS: hello world feature - core, protobuf, trezorlib, tests

hello-world
grdddj 2 years ago committed by obrusvit
parent ed1785a985
commit e1cbb8a970

@ -0,0 +1,28 @@
syntax = "proto2";
package hw.trezor.messages.helloworld;
// Sugar for easier handling in Java
option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageHelloWorld";
import "messages.proto";
/**
* Request: Hello world request for text
* @next HelloWorldResponse
* @next Failure
*/
message HelloWorldRequest {
required string name = 1;
optional uint32 amount = 2 [default=1];
optional bool show_display = 3;
}
/**
* Response: Hello world text
* @end
*/
message HelloWorldResponse {
required string text = 1;
}

@ -372,4 +372,8 @@ enum MessageType {
MessageType_SolanaAddress = 903 [(wire_out) = true];
MessageType_SolanaSignTx = 904 [(wire_in) = true];
MessageType_SolanaTxSignature = 905 [(wire_out) = true];
// Hello world
MessageType_HelloWorldRequest = 1000 [(wire_in) = true];
MessageType_HelloWorldResponse = 1001 [(wire_out) = true];
}

@ -365,6 +365,8 @@ apps.misc.get_entropy
import apps.misc.get_entropy
apps.misc.get_firmware_hash
import apps.misc.get_firmware_hash
apps.misc.hello_world
import apps.misc.hello_world
apps.misc.sign_identity
import apps.misc.sign_identity
apps.workflow_handlers

@ -0,0 +1,23 @@
from typing import TYPE_CHECKING
from trezor.messages import HelloWorldResponse
from trezor.ui.layouts import confirm_text
if TYPE_CHECKING:
from trezor.messages import HelloWorldRequest
async def hello_world(msg: HelloWorldRequest) -> HelloWorldResponse:
text = _get_text_from_msg(msg)
if msg.show_display:
await confirm_text(
"confirm_hello_world",
"Hello world",
text,
description="Hello world example",
)
return HelloWorldResponse(text=text)
def _get_text_from_msg(msg: HelloWorldRequest) -> str:
return msg.amount * f"Hello {msg.name}!\n"

@ -93,6 +93,8 @@ def _find_message_handler_module(msg_type: int) -> str:
return "apps.misc.get_firmware_hash"
if msg_type == MessageType.CosiCommit:
return "apps.misc.cosi_commit"
if msg_type == MessageType.HelloWorldRequest:
return "apps.misc.hello_world"
if not utils.BITCOIN_ONLY:
if msg_type == MessageType.SetU2FCounter:

@ -243,3 +243,5 @@ if not utils.BITCOIN_ONLY:
SolanaAddress = 903
SolanaSignTx = 904
SolanaTxSignature = 905
HelloWorldRequest = 1000
HelloWorldResponse = 1001

@ -261,6 +261,8 @@ if TYPE_CHECKING:
SolanaAddress = 903
SolanaSignTx = 904
SolanaTxSignature = 905
HelloWorldRequest = 1000
HelloWorldResponse = 1001
class FailureType(IntEnum):
UnexpectedMessage = 1

@ -3923,6 +3923,38 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["EthereumAccessList"]:
return isinstance(msg, cls)
class HelloWorldRequest(protobuf.MessageType):
name: "str"
amount: "int"
show_display: "bool | None"
def __init__(
self,
*,
name: "str",
amount: "int | None" = None,
show_display: "bool | None" = None,
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["HelloWorldRequest"]:
return isinstance(msg, cls)
class HelloWorldResponse(protobuf.MessageType):
text: "str"
def __init__(
self,
*,
text: "str",
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["HelloWorldResponse"]:
return isinstance(msg, cls)
class MoneroTransactionSourceEntry(protobuf.MessageType):
outputs: "list[MoneroOutputEntry]"
real_output: "int | None"

@ -0,0 +1,14 @@
from common import *
from trezor.messages import HelloWorldRequest
from apps.misc.hello_world import _get_text_from_msg
class TestHelloWorld(unittest.TestCase):
def test_get_text_from_msg(self):
msg = HelloWorldRequest(name="Satoshi", amount=2, show_display=False)
self.assertEqual(_get_text_from_msg(msg), "Hello Satoshi!\nHello Satoshi!\n")
if __name__ == "__main__":
unittest.main()

@ -9,7 +9,8 @@ SKIPPED_MESSAGES := Binance Cardano DebugMonero Eos Monero Ontology Ripple SdPro
EthereumSignTypedData EthereumTypedDataStructRequest EthereumTypedDataStructAck \
EthereumTypedDataValueRequest EthereumTypedDataValueAck ShowDeviceTutorial \
UnlockBootloader AuthenticateDevice AuthenticityProof \
Solana StellarClaimClaimableBalanceOp
Solana StellarClaimClaimableBalanceOp \
HelloWorldRequest HelloWorldResponse
ifeq ($(BITCOIN_ONLY), 1)
SKIPPED_MESSAGES += Ethereum NEM Stellar

@ -0,0 +1,28 @@
from typing import TYPE_CHECKING, Optional
import click
from .. import hello_world
from . import with_client
if TYPE_CHECKING:
from ..client import TrezorClient
@click.group(name="helloworld")
def cli() -> None:
"""Hello world commands."""
@cli.command()
@click.argument("name")
@click.option("-a", "--amount", type=int, help="How many times to greet.")
@click.option(
"-d", "--show-display", is_flag=True, help="Whether to show confirmation screen."
)
@with_client
def say_hello(
client: "TrezorClient", name: str, amount: Optional[int], show_display: bool
) -> str:
"""Simply say hello to the supplied name."""
return hello_world.say_hello(client, name, amount, show_display=show_display)

@ -42,6 +42,7 @@ from . import (
ethereum,
fido,
firmware,
hello_world,
monero,
nem,
ripple,
@ -407,6 +408,7 @@ cli.add_command(crypto.cli)
cli.add_command(device.cli)
cli.add_command(eos.cli)
cli.add_command(ethereum.cli)
cli.add_command(hello_world.cli)
cli.add_command(fido.cli)
cli.add_command(monero.cli)
cli.add_command(nem.cli)

@ -0,0 +1,24 @@
from typing import TYPE_CHECKING, Optional
from . import messages
from .tools import expect
if TYPE_CHECKING:
from .client import TrezorClient
from .protobuf import MessageType
@expect(messages.HelloWorldResponse, field="text", ret_type=str)
def say_hello(
client: "TrezorClient",
name: str,
amount: Optional[int],
show_display: bool,
) -> "MessageType":
return client.call(
messages.HelloWorldRequest(
name=name,
amount=amount,
show_display=show_display,
)
)

@ -269,6 +269,8 @@ class MessageType(IntEnum):
SolanaAddress = 903
SolanaSignTx = 904
SolanaTxSignature = 905
HelloWorldRequest = 1000
HelloWorldResponse = 1001
class FailureType(IntEnum):
@ -5211,6 +5213,40 @@ class EthereumAccessList(protobuf.MessageType):
self.address = address
class HelloWorldRequest(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 1000
FIELDS = {
1: protobuf.Field("name", "string", repeated=False, required=True),
2: protobuf.Field("amount", "uint32", repeated=False, required=False, default=1),
3: protobuf.Field("show_display", "bool", repeated=False, required=False, default=None),
}
def __init__(
self,
*,
name: "str",
amount: Optional["int"] = 1,
show_display: Optional["bool"] = None,
) -> None:
self.name = name
self.amount = amount
self.show_display = show_display
class HelloWorldResponse(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 1001
FIELDS = {
1: protobuf.Field("text", "string", repeated=False, required=True),
}
def __init__(
self,
*,
text: "str",
) -> None:
self.text = text
class MoneroTransactionSourceEntry(protobuf.MessageType):
MESSAGE_WIRE_TYPE = None
FIELDS = {

@ -246,6 +246,8 @@ trezor_message_impl! {
SolanaAddress => MessageType_SolanaAddress,
SolanaSignTx => MessageType_SolanaSignTx,
SolanaTxSignature => MessageType_SolanaTxSignature,
HelloWorldRequest => MessageType_HelloWorldRequest,
HelloWorldResponse => MessageType_HelloWorldResponse,
}
#[cfg(feature = "stellar")]

@ -508,6 +508,10 @@ pub enum MessageType {
MessageType_SolanaSignTx = 904,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SolanaTxSignature)
MessageType_SolanaTxSignature = 905,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_HelloWorldRequest)
MessageType_HelloWorldRequest = 1000,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_HelloWorldResponse)
MessageType_HelloWorldResponse = 1001,
}
impl ::protobuf::Enum for MessageType {
@ -759,6 +763,8 @@ impl ::protobuf::Enum for MessageType {
903 => ::std::option::Option::Some(MessageType::MessageType_SolanaAddress),
904 => ::std::option::Option::Some(MessageType::MessageType_SolanaSignTx),
905 => ::std::option::Option::Some(MessageType::MessageType_SolanaTxSignature),
1000 => ::std::option::Option::Some(MessageType::MessageType_HelloWorldRequest),
1001 => ::std::option::Option::Some(MessageType::MessageType_HelloWorldResponse),
_ => ::std::option::Option::None
}
}
@ -1005,6 +1011,8 @@ impl ::protobuf::Enum for MessageType {
"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),
"MessageType_HelloWorldRequest" => ::std::option::Option::Some(MessageType::MessageType_HelloWorldRequest),
"MessageType_HelloWorldResponse" => ::std::option::Option::Some(MessageType::MessageType_HelloWorldResponse),
_ => ::std::option::Option::None
}
}
@ -1250,6 +1258,8 @@ impl ::protobuf::Enum for MessageType {
MessageType::MessageType_SolanaAddress,
MessageType::MessageType_SolanaSignTx,
MessageType::MessageType_SolanaTxSignature,
MessageType::MessageType_HelloWorldRequest,
MessageType::MessageType_HelloWorldResponse,
];
}
@ -1501,6 +1511,8 @@ impl ::protobuf::EnumFull for MessageType {
MessageType::MessageType_SolanaAddress => 237,
MessageType::MessageType_SolanaSignTx => 238,
MessageType::MessageType_SolanaTxSignature => 239,
MessageType::MessageType_HelloWorldRequest => 240,
MessageType::MessageType_HelloWorldResponse => 241,
};
Self::enum_descriptor().value_by_index(index)
}
@ -1550,7 +1562,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*\x8bS\n\x0bMessageType\x12(\n\x16MessageType_Initialize\
scriptor.proto*\xe0S\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\
@ -1821,30 +1833,32 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x07\x1a\x04\x90\xb5\x18\x01\x12$\n\x19MessageType_SolanaAddress\x10\x87\
\x07\x1a\x04\x98\xb5\x18\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\xdb\x01\x10\xdb\x01\"\x06\x08\xe0\x01\x10\
\xe0\x01\"\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.EnumValueO\
ptionsR\x06wireIn:>\n\x08wire_out\x18\xd3\x86\x03\x20\x01(\x08\x12!.goog\
le.protobuf.EnumValueOptionsR\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_boo\
tloader\x18\xd7\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptio\
nsR\x0ewireBootloader:C\n\x0bwire_no_fsm\x18\xd8\x86\x03\x20\x01(\x08\
\x12!.google.protobuf.EnumValueOptionsR\twireNoFsm:F\n\x0cbitcoin_only\
\x18\xe0\xd4\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0b\
bitcoinOnly:U\n\x17has_bitcoin_only_values\x18\xb9\x8e\x03\x20\x01(\x08\
\x12\x1c.google.protobuf.EnumOptionsR\x14hasBitcoinOnlyValues:T\n\x14exp\
erimental_message\x18\xa1\x96\x03\x20\x01(\x08\x12\x1f.google.protobuf.M\
essageOptionsR\x13experimentalMessage:>\n\twire_type\x18\xa2\x96\x03\x20\
\x01(\r\x12\x1f.google.protobuf.MessageOptionsR\x08wireType:N\n\x12exper\
imental_field\x18\x89\x9e\x03\x20\x01(\x08\x12\x1d.google.protobuf.Field\
OptionsR\x11experimentalField:U\n\x17include_in_bitcoin_only\x18\xe0\xd4\
\x03\x20\x01(\x08\x12\x1c.google.protobuf.FileOptionsR\x14includeInBitco\
inOnlyB8\n#com.satoshilabs.trezor.lib.protobufB\rTrezorMessage\x80\xa6\
\x1d\x01\
\x89\x07\x1a\x04\x98\xb5\x18\x01\x12(\n\x1dMessageType_HelloWorldRequest\
\x10\xe8\x07\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMessageType_HelloWorldRes\
ponse\x10\xe9\x07\x1a\x04\x98\xb5\x18\x01\x1a\x04\xc8\xf3\x18\x01\"\x04\
\x08Z\x10\\\"\x04\x08r\x10z\"\x06\x08\xdb\x01\x10\xdb\x01\"\x06\x08\xe0\
\x01\x10\xe0\x01\"\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.En\
umValueOptionsR\x06wireIn:>\n\x08wire_out\x18\xd3\x86\x03\x20\x01(\x08\
\x12!.google.protobuf.EnumValueOptionsR\x07wireOut:G\n\rwire_debug_in\
\x18\xd4\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0b\
wireDebugIn:I\n\x0ewire_debug_out\x18\xd5\x86\x03\x20\x01(\x08\x12!.goog\
le.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.En\
umValueOptionsR\x0ewireBootloader:C\n\x0bwire_no_fsm\x18\xd8\x86\x03\x20\
\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\twireNoFsm:F\n\x0cbitco\
in_only\x18\xe0\xd4\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptio\
nsR\x0bbitcoinOnly:U\n\x17has_bitcoin_only_values\x18\xb9\x8e\x03\x20\
\x01(\x08\x12\x1c.google.protobuf.EnumOptionsR\x14hasBitcoinOnlyValues:T\
\n\x14experimental_message\x18\xa1\x96\x03\x20\x01(\x08\x12\x1f.google.p\
rotobuf.MessageOptionsR\x13experimentalMessage:>\n\twire_type\x18\xa2\
\x96\x03\x20\x01(\r\x12\x1f.google.protobuf.MessageOptionsR\x08wireType:\
N\n\x12experimental_field\x18\x89\x9e\x03\x20\x01(\x08\x12\x1d.google.pr\
otobuf.FieldOptionsR\x11experimentalField:U\n\x17include_in_bitcoin_only\
\x18\xe0\xd4\x03\x20\x01(\x08\x12\x1c.google.protobuf.FileOptionsR\x14in\
cludeInBitcoinOnlyB8\n#com.satoshilabs.trezor.lib.protobufB\rTrezorMessa\
ge\x80\xa6\x1d\x01\
";
/// `FileDescriptorProto` object which was a source for this generated file

@ -0,0 +1,462 @@
// This file is generated by rust-protobuf 3.3.0. Do not edit
// .proto file is parsed by protoc 3.19.6
// @generated
// https://github.com/rust-lang/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]
#![allow(unused_attributes)]
#![cfg_attr(rustfmt, rustfmt::skip)]
#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unused_results)]
#![allow(unused_mut)]
//! Generated file from `messages-hello.proto`
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_3_0;
// @@protoc_insertion_point(message:hw.trezor.messages.helloworld.HelloWorldRequest)
#[derive(PartialEq,Clone,Default,Debug)]
pub struct HelloWorldRequest {
// message fields
// @@protoc_insertion_point(field:hw.trezor.messages.helloworld.HelloWorldRequest.name)
pub name: ::std::option::Option<::std::string::String>,
// @@protoc_insertion_point(field:hw.trezor.messages.helloworld.HelloWorldRequest.amount)
pub amount: ::std::option::Option<u32>,
// @@protoc_insertion_point(field:hw.trezor.messages.helloworld.HelloWorldRequest.show_display)
pub show_display: ::std::option::Option<bool>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.helloworld.HelloWorldRequest.special_fields)
pub special_fields: ::protobuf::SpecialFields,
}
impl<'a> ::std::default::Default for &'a HelloWorldRequest {
fn default() -> &'a HelloWorldRequest {
<HelloWorldRequest as ::protobuf::Message>::default_instance()
}
}
impl HelloWorldRequest {
pub fn new() -> HelloWorldRequest {
::std::default::Default::default()
}
// required string name = 1;
pub fn name(&self) -> &str {
match self.name.as_ref() {
Some(v) => v,
None => "",
}
}
pub fn clear_name(&mut self) {
self.name = ::std::option::Option::None;
}
pub fn has_name(&self) -> bool {
self.name.is_some()
}
// Param is passed by value, moved
pub fn set_name(&mut self, v: ::std::string::String) {
self.name = ::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_name(&mut self) -> &mut ::std::string::String {
if self.name.is_none() {
self.name = ::std::option::Option::Some(::std::string::String::new());
}
self.name.as_mut().unwrap()
}
// Take field
pub fn take_name(&mut self) -> ::std::string::String {
self.name.take().unwrap_or_else(|| ::std::string::String::new())
}
// optional uint32 amount = 2;
pub fn amount(&self) -> u32 {
self.amount.unwrap_or(1u32)
}
pub fn clear_amount(&mut self) {
self.amount = ::std::option::Option::None;
}
pub fn has_amount(&self) -> bool {
self.amount.is_some()
}
// Param is passed by value, moved
pub fn set_amount(&mut self, v: u32) {
self.amount = ::std::option::Option::Some(v);
}
// optional bool show_display = 3;
pub fn show_display(&self) -> bool {
self.show_display.unwrap_or(false)
}
pub fn clear_show_display(&mut self) {
self.show_display = ::std::option::Option::None;
}
pub fn has_show_display(&self) -> bool {
self.show_display.is_some()
}
// Param is passed by value, moved
pub fn set_show_display(&mut self, v: bool) {
self.show_display = ::std::option::Option::Some(v);
}
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
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::<_, _>(
"name",
|m: &HelloWorldRequest| { &m.name },
|m: &mut HelloWorldRequest| { &mut m.name },
));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"amount",
|m: &HelloWorldRequest| { &m.amount },
|m: &mut HelloWorldRequest| { &mut m.amount },
));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"show_display",
|m: &HelloWorldRequest| { &m.show_display },
|m: &mut HelloWorldRequest| { &mut m.show_display },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<HelloWorldRequest>(
"HelloWorldRequest",
fields,
oneofs,
)
}
}
impl ::protobuf::Message for HelloWorldRequest {
const NAME: &'static str = "HelloWorldRequest";
fn is_initialized(&self) -> bool {
if self.name.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.name = ::std::option::Option::Some(is.read_string()?);
},
16 => {
self.amount = ::std::option::Option::Some(is.read_uint32()?);
},
24 => {
self.show_display = ::std::option::Option::Some(is.read_bool()?);
},
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.name.as_ref() {
my_size += ::protobuf::rt::string_size(1, &v);
}
if let Some(v) = self.amount {
my_size += ::protobuf::rt::uint32_size(2, v);
}
if let Some(v) = self.show_display {
my_size += 1 + 1;
}
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.name.as_ref() {
os.write_string(1, v)?;
}
if let Some(v) = self.amount {
os.write_uint32(2, v)?;
}
if let Some(v) = self.show_display {
os.write_bool(3, 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() -> HelloWorldRequest {
HelloWorldRequest::new()
}
fn clear(&mut self) {
self.name = ::std::option::Option::None;
self.amount = ::std::option::Option::None;
self.show_display = ::std::option::Option::None;
self.special_fields.clear();
}
fn default_instance() -> &'static HelloWorldRequest {
static instance: HelloWorldRequest = HelloWorldRequest {
name: ::std::option::Option::None,
amount: ::std::option::Option::None,
show_display: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
}
}
impl ::protobuf::MessageFull for HelloWorldRequest {
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("HelloWorldRequest").unwrap()).clone()
}
}
impl ::std::fmt::Display for HelloWorldRequest {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for HelloWorldRequest {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}
// @@protoc_insertion_point(message:hw.trezor.messages.helloworld.HelloWorldResponse)
#[derive(PartialEq,Clone,Default,Debug)]
pub struct HelloWorldResponse {
// message fields
// @@protoc_insertion_point(field:hw.trezor.messages.helloworld.HelloWorldResponse.text)
pub text: ::std::option::Option<::std::string::String>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.helloworld.HelloWorldResponse.special_fields)
pub special_fields: ::protobuf::SpecialFields,
}
impl<'a> ::std::default::Default for &'a HelloWorldResponse {
fn default() -> &'a HelloWorldResponse {
<HelloWorldResponse as ::protobuf::Message>::default_instance()
}
}
impl HelloWorldResponse {
pub fn new() -> HelloWorldResponse {
::std::default::Default::default()
}
// required string text = 1;
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())
}
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::<_, _>(
"text",
|m: &HelloWorldResponse| { &m.text },
|m: &mut HelloWorldResponse| { &mut m.text },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<HelloWorldResponse>(
"HelloWorldResponse",
fields,
oneofs,
)
}
}
impl ::protobuf::Message for HelloWorldResponse {
const NAME: &'static str = "HelloWorldResponse";
fn is_initialized(&self) -> bool {
if self.text.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.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.text.as_ref() {
my_size += ::protobuf::rt::string_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.text.as_ref() {
os.write_string(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() -> HelloWorldResponse {
HelloWorldResponse::new()
}
fn clear(&mut self) {
self.text = ::std::option::Option::None;
self.special_fields.clear();
}
fn default_instance() -> &'static HelloWorldResponse {
static instance: HelloWorldResponse = HelloWorldResponse {
text: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
}
}
impl ::protobuf::MessageFull for HelloWorldResponse {
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("HelloWorldResponse").unwrap()).clone()
}
}
impl ::std::fmt::Display for HelloWorldResponse {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for HelloWorldResponse {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x14messages-hello.proto\x12\x1dhw.trezor.messages.helloworld\x1a\x0em\
essages.proto\"e\n\x11HelloWorldRequest\x12\x12\n\x04name\x18\x01\x20\
\x02(\tR\x04name\x12\x19\n\x06amount\x18\x02\x20\x01(\r:\x011R\x06amount\
\x12!\n\x0cshow_display\x18\x03\x20\x01(\x08R\x0bshowDisplay\"(\n\x12Hel\
loWorldResponse\x12\x12\n\x04text\x18\x01\x20\x02(\tR\x04textB>\n#com.sa\
toshilabs.trezor.lib.protobufB\x17TrezorMessageHelloWorld\
";
/// `FileDescriptorProto` object which was a source for this generated file
fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
static file_descriptor_proto_lazy: ::protobuf::rt::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::Lazy::new();
file_descriptor_proto_lazy.get(|| {
::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
})
}
/// `FileDescriptor` object which allows dynamic access to files
pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
static generated_file_descriptor_lazy: ::protobuf::rt::Lazy<::protobuf::reflect::GeneratedFileDescriptor> = ::protobuf::rt::Lazy::new();
static file_descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::FileDescriptor> = ::protobuf::rt::Lazy::new();
file_descriptor.get(|| {
let generated_file_descriptor = generated_file_descriptor_lazy.get(|| {
let mut deps = ::std::vec::Vec::with_capacity(1);
deps.push(super::messages::file_descriptor().clone());
let mut messages = ::std::vec::Vec::with_capacity(2);
messages.push(HelloWorldRequest::generated_message_descriptor_data());
messages.push(HelloWorldResponse::generated_message_descriptor_data());
let mut enums = ::std::vec::Vec::with_capacity(0);
::protobuf::reflect::GeneratedFileDescriptor::new_generated(
file_descriptor_proto(),
deps,
messages,
enums,
)
});
::protobuf::reflect::FileDescriptor::new_generated_2(generated_file_descriptor)
})
}

@ -0,0 +1,43 @@
# This file is part of the Trezor project.
#
# Copyright (C) 2012-2019 SatoshiLabs and contributors
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
from typing import Optional
import pytest
from trezorlib import hello_world
from trezorlib.debuglink import TrezorClientDebugLink as Client
VECTORS = ( # name, amount, show_display
("George", 2, True),
("John", 3, False),
("Hannah", None, False),
)
@pytest.mark.skip_t1
@pytest.mark.parametrize("name, amount, show_display", VECTORS)
def test_hello_world(
client: Client, name: str, amount: Optional[int], show_display: bool
):
with client:
greeting_text = hello_world.say_hello(
client, name=name, amount=amount, show_display=show_display
)
greeting_lines = greeting_text.strip().splitlines()
assert len(greeting_lines) == amount or 1
assert all(name in line for line in greeting_lines)

@ -3139,6 +3139,9 @@
"TT_misc-test_cosi.py::test_slip26_paths[\\x00-3]": "2cbaa2088776f1c7c735aa1ef767d33f8ad8ebdb592b6d9814dd1bbabd6da9b5",
"TT_misc-test_cosi.py::test_slip26_paths[\\xfe\\xfe\\xfe\\xfe-0]": "58a16c31957f7d540da34a30f54631e607eca1af6efb27a0b3877e49f77a9d56",
"TT_misc-test_cosi.py::test_slip26_paths[dog-0]": "7cee26436a0025a56eb1f67e432e4e707857714c1bbf5f61df60cc20f54c84ab",
"TT_misc-test_hello_world.py::test_hello_world[George-2-True]": "061e096ed3b47be216f4c7eb01999b4ec8bace1e3608a0de1fc128747b28a060",
"TT_misc-test_hello_world.py::test_hello_world[Hannah-None-False]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_misc-test_hello_world.py::test_hello_world[John-3-False]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_misc-test_msg_cipherkeyvalue.py::test_decrypt": "b34ae9ac7b3ea7467afe774bf615ca1e1eab26c64fe5d25178071bf15e8d6518",
"TT_misc-test_msg_cipherkeyvalue.py::test_decrypt_badlen": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_misc-test_msg_cipherkeyvalue.py::test_encrypt": "648e45403ce412314e9d91625ace8ffdee52ff37ac99b13f4e86d018a024515d",

Loading…
Cancel
Save