1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 22:38:08 +00:00

fix(core/ui): T2T1: update sign message layout

This commit is contained in:
Martin Milata 2023-10-19 17:29:29 +02:00
parent 9e33eb3e48
commit 18d6b4d647
23 changed files with 693 additions and 365 deletions

View File

@ -155,6 +155,7 @@ message SignMessage {
optional string coin_name = 3 [default='Bitcoin']; // coin to use for signing
optional InputScriptType script_type = 4 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.)
optional bool no_script_type = 5; // don't include script type information in the recovery byte of the signature, same as in Bitcoin Core
optional bool chunkify = 6; // display the address in chunks of 4 characters
}
/**
@ -177,6 +178,7 @@ message VerifyMessage {
required bytes signature = 2; // signature to verify
required bytes message = 3; // message to verify
optional string coin_name = 4 [default='Bitcoin']; // coin to use for verifying
optional bool chunkify = 5; // display the address in chunks of 4 characters
}
/**

View File

@ -135,6 +135,7 @@ message EthereumSignMessage {
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
required bytes message = 2; // message to be signed
optional bytes encoded_network = 3; // encoded Ethereum network, see ethereum-definitions.md for details
optional bool chunkify = 4; // display the address in chunks of 4 characters
}
/**
@ -156,6 +157,7 @@ message EthereumVerifyMessage {
required bytes signature = 2; // signature to verify
required bytes message = 3; // message to verify
required string address = 4; // address to verify
optional bool chunkify = 5; // display the address in chunks of 4 characters
}
/**

View File

@ -75,6 +75,7 @@ static void _librust_qstrs(void) {
MP_QSTR_fee_rate_amount;
MP_QSTR_hold;
MP_QSTR_hold_danger;
MP_QSTR_horizontal;
MP_QSTR_icon_name;
MP_QSTR_image;
MP_QSTR_indeterminate;

View File

@ -637,20 +637,20 @@ pub struct LinearPlacement {
}
impl LinearPlacement {
pub const fn horizontal() -> Self {
pub const fn new(axis: Axis) -> Self {
Self {
axis: Axis::Horizontal,
axis,
align: Alignment::Start,
spacing: 0,
}
}
pub const fn horizontal() -> Self {
Self::new(Axis::Horizontal)
}
pub const fn vertical() -> Self {
Self {
axis: Axis::Vertical,
align: Alignment::Start,
spacing: 0,
}
Self::new(Axis::Vertical)
}
pub const fn align_at_start(self) -> Self {

View File

@ -824,12 +824,13 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let address: StrBuffer = kwargs.get(Qstr::MP_QSTR_data)?.try_into()?;
let verb: StrBuffer = kwargs.get_or(Qstr::MP_QSTR_verb, "CONFIRM".into())?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let get_page = move |page_index| {
assert!(page_index == 0);
let btn_layout = ButtonLayout::cancel_armed_info("CONFIRM".into());
let btn_layout = ButtonLayout::cancel_armed_info(verb.clone());
let btn_actions = ButtonActions::cancel_confirm_info();
let style = if chunkify {
// Chunkifying the address into smaller pieces when requested
@ -1671,6 +1672,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// data: str,
/// description: str | None, # unused on TR
/// extra: str | None, # unused on TR
/// verb: str = "CONFIRM",
/// chunkify: bool = False,
/// ) -> object:
/// """Confirm address."""

View File

@ -1,7 +1,7 @@
use crate::ui::{
component::{Component, Event, EventCtx, Never},
display::toif::Icon,
geometry::{Alignment2D, LinearPlacement, Offset, Rect},
geometry::{Alignment2D, Axis, LinearPlacement, Offset, Rect},
};
use super::theme;
@ -21,7 +21,8 @@ impl ScrollBar {
/// Center to center.
const DOT_INTERVAL: i16 = 18;
fn new(layout: LinearPlacement) -> Self {
pub fn new(axis: Axis) -> Self {
let layout = LinearPlacement::new(axis);
Self {
area: Rect::zero(),
layout: layout.align_at_center().with_spacing(Self::DOT_INTERVAL),
@ -31,11 +32,11 @@ impl ScrollBar {
}
pub fn vertical() -> Self {
Self::new(LinearPlacement::vertical())
Self::new(Axis::Vertical)
}
pub fn horizontal() -> Self {
Self::new(LinearPlacement::horizontal())
Self::new(Axis::Horizontal)
}
pub fn set_count_and_active_page(&mut self, page_count: usize, active_page: usize) {

View File

@ -24,28 +24,24 @@ where
T: Paginate,
T: Component,
{
pub fn horizontal(content: T, background: Color) -> Self {
pub fn new(content: T, axis: Axis, background: Color) -> Self {
Self {
content,
swipe: Swipe::new(),
pad: Pad::with_background(background),
scrollbar: ScrollBar::horizontal(),
axis: Axis::Horizontal,
scrollbar: ScrollBar::new(axis),
axis,
swipe_right_to_go_back: false,
fade: None,
}
}
pub fn horizontal(content: T, background: Color) -> Self {
Self::new(content, Axis::Horizontal, background)
}
pub fn vertical(content: T, background: Color) -> Self {
Self {
content,
swipe: Swipe::new(),
pad: Pad::with_background(background),
scrollbar: ScrollBar::vertical(),
axis: Axis::Vertical,
swipe_right_to_go_back: false,
fade: None,
}
Self::new(content, Axis::Vertical, background)
}
pub fn with_swipe_right_to_go_back(mut self) -> Self {

View File

@ -517,13 +517,13 @@ impl ConfirmBlobParams {
}
.into_paragraphs();
let page: ButtonPage<_, StrBuffer> = if self.hold {
ButtonPage::new(paragraphs, theme::BG).with_hold()
} else if let Some(verb) = self.verb {
ButtonPage::new(paragraphs, theme::BG).with_cancel_confirm(self.verb_cancel, Some(verb))
} else {
panic!("Either `hold=true` or `verb=Some(StrBuffer)` must be specified");
};
let mut page = ButtonPage::new(paragraphs, theme::BG);
if let Some(verb) = self.verb {
page = page.with_cancel_confirm(self.verb_cancel, Some(verb))
}
if self.hold {
page = page.with_hold()
}
let mut frame = Frame::left_aligned(theme::label_title(), self.title, page);
if let Some(subtitle) = self.subtitle {
frame = frame.with_subtitle(theme::label_subtitle(), subtitle);
@ -567,6 +567,7 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: Option<StrBuffer> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let verb: StrBuffer = kwargs.get_or(Qstr::MP_QSTR_verb, "CONFIRM".into())?;
let extra: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_extra)?.try_into_option()?;
let data: Obj = kwargs.get(Qstr::MP_QSTR_data)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
@ -601,7 +602,7 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
title,
ButtonPage::new(paragraphs, theme::BG)
.with_swipe_left()
.with_cancel_confirm(None, Some("CONFIRM")),
.with_cancel_confirm(None, Some(verb)),
)
.with_info_button(),
)?;
@ -737,6 +738,7 @@ extern "C" fn new_show_info_with_cancel(n_args: usize, args: *const Obj, kwargs:
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let horizontal: bool = kwargs.get_or(Qstr::MP_QSTR_horizontal, false)?;
let mut paragraphs = ParagraphVecShort::new();
@ -748,11 +750,16 @@ extern "C" fn new_show_info_with_cancel(n_args: usize, args: *const Obj, kwargs:
paragraphs.add(Paragraph::new(&theme::TEXT_MONO, value));
}
let axis = match horizontal {
true => geometry::Axis::Horizontal,
_ => geometry::Axis::Vertical,
};
let obj = LayoutObj::new(
Frame::left_aligned(
theme::label_title(),
title,
SimplePage::vertical(paragraphs.into_paragraphs(), theme::BG)
SimplePage::new(paragraphs.into_paragraphs(), axis, theme::BG)
.with_swipe_right_to_go_back(),
)
.with_cancel_button(),
@ -1655,6 +1662,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str,
/// data: str | bytes,
/// description: str | None,
/// verb: str | None = "CONFIRM",
/// extra: str | None,
/// chunkify: bool = False,
/// ) -> object:
@ -1697,8 +1705,9 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// *,
/// title: str,
/// items: Iterable[Tuple[str, str]],
/// horizontal: bool = False,
/// ) -> object:
/// """Show metadata when for outgoing transaction."""
/// """Show metadata for outgoing transaction."""
Qstr::MP_QSTR_show_info_with_cancel => obj_fn_kw!(0, new_show_info_with_cancel).as_obj(),
/// def confirm_value(

View File

@ -60,6 +60,7 @@ def confirm_address(
data: str,
description: str | None, # unused on TR
extra: str | None, # unused on TR
verb: str = "CONFIRM",
chunkify: bool = False,
) -> object:
"""Confirm address."""
@ -517,6 +518,7 @@ def confirm_address(
title: str,
data: str | bytes,
description: str | None,
verb: str | None = "CONFIRM",
extra: str | None,
chunkify: bool = False,
) -> object:
@ -563,8 +565,9 @@ def show_info_with_cancel(
*,
title: str,
items: Iterable[Tuple[str, str]],
horizontal: bool = False,
) -> object:
"""Show metadata when for outgoing transaction."""
"""Show metadata for outgoing transaction."""
# rust/src/ui/model_tt/layout.rs

View File

@ -39,7 +39,10 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
from apps.common.paths import address_n_to_str, validate_path
from . import addresses
from .keychain import address_n_to_name, validate_path_against_script_type
from .keychain import (
address_n_to_name_or_unknown,
validate_path_against_script_type,
)
from .multisig import multisig_pubkey_index
multisig = msg.multisig # local_cache_attribute
@ -116,13 +119,7 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
chunkify=bool(msg.chunkify),
)
else:
account_name = address_n_to_name(coin, address_n, script_type)
if account_name is None:
account = "Unknown path"
elif account_name == "":
account = coin.coin_shortcut
else:
account = f"{coin.coin_shortcut} {account_name}"
account = address_n_to_name_or_unknown(coin, address_n, script_type)
await show_address(
address_short,
address_qr=address,

View File

@ -455,3 +455,19 @@ def address_n_to_name(
return name
return None
def address_n_to_name_or_unknown(
coin: coininfo.CoinInfo,
address_n: Bip32Path,
script_type: InputScriptType | None = None,
account_level: bool = False,
show_account_str: bool = False,
) -> str:
account_name = address_n_to_name(coin, address_n, script_type)
if account_name is None:
return "Unknown path"
elif account_name == "":
return coin.coin_shortcut
else:
return f"{coin.coin_shortcut} {account_name}"

View File

@ -19,11 +19,14 @@ async def sign_message(
from trezor.messages import MessageSignature
from trezor.ui.layouts import confirm_signverify
from apps.common.paths import validate_path
from apps.common.paths import address_n_to_str, validate_path
from apps.common.signverify import decode_message, message_digest
from .addresses import address_short, get_address
from .keychain import validate_path_against_script_type
from .keychain import (
address_n_to_name_or_unknown,
validate_path_against_script_type,
)
message = msg.message
address_n = msg.address_n
@ -35,11 +38,15 @@ async def sign_message(
node = keychain.derive(address_n)
address = get_address(script_type, coin, node)
path = address_n_to_str(address_n)
account = address_n_to_name_or_unknown(coin, address_n, script_type)
await confirm_signverify(
coin.coin_shortcut,
decode_message(message),
address_short(coin, address),
verify=False,
account=account,
path=path,
chunkify=bool(msg.chunkify),
)
seckey = node.private_key()

View File

@ -111,7 +111,6 @@ async def verify_message(msg: VerifyMessage) -> Success:
raise ProcessError("Invalid signature")
await confirm_signverify(
coin.coin_shortcut,
decode_message(message),
address_short(coin, address),
verify=True,

View File

@ -41,7 +41,10 @@ async def sign_message(
node = keychain.derive(msg.address_n)
address = address_from_bytes(node.ethereum_pubkeyhash(), defs.network)
await confirm_signverify("ETH", decode_message(msg.message), address, verify=False)
path = paths.address_n_to_str(msg.address_n)
await confirm_signverify(
decode_message(msg.message), address, account="ETH", path=path, verify=False
)
signature = secp256k1.sign(
node.private_key(),

View File

@ -34,7 +34,7 @@ async def verify_message(msg: EthereumVerifyMessage) -> Success:
address = address_from_bytes(address_bytes)
await confirm_signverify("ETH", decode_message(msg.message), address, verify=True)
await confirm_signverify(decode_message(msg.message), address, verify=True)
await show_success("verify_message", "The signature is valid.")
return Success(message="Message verified")

View File

@ -542,6 +542,7 @@ if TYPE_CHECKING:
coin_name: "str"
script_type: "InputScriptType"
no_script_type: "bool | None"
chunkify: "bool | None"
def __init__(
self,
@ -551,6 +552,7 @@ if TYPE_CHECKING:
coin_name: "str | None" = None,
script_type: "InputScriptType | None" = None,
no_script_type: "bool | None" = None,
chunkify: "bool | None" = None,
) -> None:
pass
@ -579,6 +581,7 @@ if TYPE_CHECKING:
signature: "bytes"
message: "bytes"
coin_name: "str"
chunkify: "bool | None"
def __init__(
self,
@ -587,6 +590,7 @@ if TYPE_CHECKING:
signature: "bytes",
message: "bytes",
coin_name: "str | None" = None,
chunkify: "bool | None" = None,
) -> None:
pass
@ -3804,6 +3808,7 @@ if TYPE_CHECKING:
address_n: "list[int]"
message: "bytes"
encoded_network: "bytes | None"
chunkify: "bool | None"
def __init__(
self,
@ -3811,6 +3816,7 @@ if TYPE_CHECKING:
message: "bytes",
address_n: "list[int] | None" = None,
encoded_network: "bytes | None" = None,
chunkify: "bool | None" = None,
) -> None:
pass
@ -3838,6 +3844,7 @@ if TYPE_CHECKING:
signature: "bytes"
message: "bytes"
address: "str"
chunkify: "bool | None"
def __init__(
self,
@ -3845,6 +3852,7 @@ if TYPE_CHECKING:
signature: "bytes",
message: "bytes",
address: "str",
chunkify: "bool | None" = None,
) -> None:
pass

View File

@ -1139,7 +1139,12 @@ async def confirm_sign_identity(
async def confirm_signverify(
coin: str, message: str, address: str, verify: bool
message: str,
address: str,
verify: bool,
path: str | None = None,
account: str | None = None,
chunkify: bool = False,
) -> None:
br_type = "verify_message" if verify else "sign_message"

View File

@ -414,6 +414,7 @@ async def show_address(
multisig_index: int | None = None,
xpubs: Sequence[str] = (),
mismatch_title: str = "Address mismatch?",
details_title: str | None = None,
br_type: str = "show_address",
br_code: ButtonRequestType = ButtonRequestType.Address,
chunkify: bool = False,
@ -426,7 +427,7 @@ async def show_address(
else "RECEIVE ADDRESS"
)
details_title = "RECEIVING TO"
else:
elif details_title is None:
details_title = title
while True:
layout = RustLayout(
@ -927,7 +928,7 @@ async def confirm_total(
items=items,
)
)
await with_info(total_layout, info_layout, br_type, br_code)
await raise_if_not_confirmed(with_info(total_layout, info_layout, br_type, br_code))
async def confirm_ethereum_tx(
@ -969,7 +970,9 @@ async def confirm_ethereum_tx(
try:
total_layout.request_complete_repaint()
await with_info(total_layout, info_layout, br_type, br_code)
await raise_if_not_confirmed(
with_info(total_layout, info_layout, br_type, br_code)
)
break
except ActionCancelled:
continue
@ -1079,22 +1082,20 @@ async def with_info(
info_layout: RustLayout,
br_type: str,
br_code: ButtonRequestType,
) -> None:
) -> Any:
await button_request(br_type, br_code, pages=main_layout.page_count())
while True:
result = await ctx_wait(main_layout)
if result is CONFIRMED:
return
elif result is INFO:
if result is INFO:
info_layout.request_complete_repaint()
result = await ctx_wait(info_layout)
assert result is CANCELLED
main_layout.request_complete_repaint()
continue
raise ActionCancelled
else:
return result
async def confirm_modify_fee(
@ -1122,7 +1123,9 @@ async def confirm_modify_fee(
items=items,
)
)
await with_info(fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx)
await raise_if_not_confirmed(
with_info(fee_layout, info_layout, "modify_fee", ButtonRequestType.SignTx)
)
async def confirm_coinjoin(max_rounds: int, max_fee_per_vbyte: str) -> None:
@ -1154,32 +1157,80 @@ async def confirm_sign_identity(
async def confirm_signverify(
coin: str, message: str, address: str, verify: bool
message: str,
address: str,
verify: bool,
path: str | None = None,
account: str | None = None,
chunkify: bool = False,
) -> None:
if verify:
title = f"VERIFY {coin} MESSAGE"
address_title = "VERIFY ADDRESS"
br_type = "verify_message"
else:
title = f"SIGN {coin} MESSAGE"
address_title = "SIGNING ADDRESS"
br_type = "sign_message"
await confirm_blob(
br_type,
title,
address,
"Confirm address:",
br_code=BR_TYPE_OTHER,
address_layout = RustLayout(
trezorui2.confirm_address(
title=address_title,
data=address,
description="",
verb="CONTINUE",
extra=None,
chunkify=chunkify,
)
)
await confirm_blob(
br_type,
title,
message,
"Confirm message:",
hold=not verify,
br_code=BR_TYPE_OTHER,
items: list[tuple[str, str]] = []
if account is not None:
items.append(("Account:", account))
if path is not None:
items.append(("Derivation path:", path))
items.append(("Message size:", f"{len(message)} Bytes"))
info_layout = RustLayout(
trezorui2.show_info_with_cancel(
title="INFORMATION",
items=items,
horizontal=True,
)
)
message_layout = RustLayout(
trezorui2.confirm_blob(
title="CONFIRM MESSAGE",
description=None,
data=message,
extra=None,
hold=not verify,
verb="CONFIRM" if verify else None,
)
)
while True:
result = await with_info(
address_layout, info_layout, br_type, br_code=BR_TYPE_OTHER
)
if result is not CONFIRMED:
result = await ctx_wait(
RustLayout(trezorui2.show_mismatch(title="Address mismatch?"))
)
assert result in (CONFIRMED, CANCELLED)
# Right button aborts action, left goes back to showing address.
if result is CONFIRMED:
raise ActionCancelled
else:
address_layout.request_complete_repaint()
continue
message_layout.request_complete_repaint()
result = await interact(message_layout, br_type, BR_TYPE_OTHER)
if result is CONFIRMED:
break
address_layout.request_complete_repaint()
async def show_error_popup(
title: str,

View File

@ -1970,6 +1970,8 @@ pub struct SignMessage {
pub script_type: ::std::option::Option<::protobuf::EnumOrUnknown<InputScriptType>>,
// @@protoc_insertion_point(field:hw.trezor.messages.bitcoin.SignMessage.no_script_type)
pub no_script_type: ::std::option::Option<bool>,
// @@protoc_insertion_point(field:hw.trezor.messages.bitcoin.SignMessage.chunkify)
pub chunkify: ::std::option::Option<bool>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.bitcoin.SignMessage.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@ -2099,8 +2101,27 @@ impl SignMessage {
self.no_script_type = ::std::option::Option::Some(v);
}
// optional bool chunkify = 6;
pub fn chunkify(&self) -> bool {
self.chunkify.unwrap_or(false)
}
pub fn clear_chunkify(&mut self) {
self.chunkify = ::std::option::Option::None;
}
pub fn has_chunkify(&self) -> bool {
self.chunkify.is_some()
}
// Param is passed by value, moved
pub fn set_chunkify(&mut self, v: bool) {
self.chunkify = ::std::option::Option::Some(v);
}
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
let mut fields = ::std::vec::Vec::with_capacity(5);
let mut fields = ::std::vec::Vec::with_capacity(6);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
"address_n",
@ -2127,6 +2148,11 @@ impl SignMessage {
|m: &SignMessage| { &m.no_script_type },
|m: &mut SignMessage| { &mut m.no_script_type },
));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"chunkify",
|m: &SignMessage| { &m.chunkify },
|m: &mut SignMessage| { &mut m.chunkify },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SignMessage>(
"SignMessage",
fields,
@ -2166,6 +2192,9 @@ impl ::protobuf::Message for SignMessage {
40 => {
self.no_script_type = ::std::option::Option::Some(is.read_bool()?);
},
48 => {
self.chunkify = ::std::option::Option::Some(is.read_bool()?);
},
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@ -2193,6 +2222,9 @@ impl ::protobuf::Message for SignMessage {
if let Some(v) = self.no_script_type {
my_size += 1 + 1;
}
if let Some(v) = self.chunkify {
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
@ -2214,6 +2246,9 @@ impl ::protobuf::Message for SignMessage {
if let Some(v) = self.no_script_type {
os.write_bool(5, v)?;
}
if let Some(v) = self.chunkify {
os.write_bool(6, v)?;
}
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@ -2236,6 +2271,7 @@ impl ::protobuf::Message for SignMessage {
self.coin_name = ::std::option::Option::None;
self.script_type = ::std::option::Option::None;
self.no_script_type = ::std::option::Option::None;
self.chunkify = ::std::option::Option::None;
self.special_fields.clear();
}
@ -2246,6 +2282,7 @@ impl ::protobuf::Message for SignMessage {
coin_name: ::std::option::Option::None,
script_type: ::std::option::Option::None,
no_script_type: ::std::option::Option::None,
chunkify: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@ -2499,6 +2536,8 @@ pub struct VerifyMessage {
pub message: ::std::option::Option<::std::vec::Vec<u8>>,
// @@protoc_insertion_point(field:hw.trezor.messages.bitcoin.VerifyMessage.coin_name)
pub coin_name: ::std::option::Option<::std::string::String>,
// @@protoc_insertion_point(field:hw.trezor.messages.bitcoin.VerifyMessage.chunkify)
pub chunkify: ::std::option::Option<bool>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.bitcoin.VerifyMessage.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@ -2659,8 +2698,27 @@ impl VerifyMessage {
self.coin_name.take().unwrap_or_else(|| ::std::string::String::new())
}
// optional bool chunkify = 5;
pub fn chunkify(&self) -> bool {
self.chunkify.unwrap_or(false)
}
pub fn clear_chunkify(&mut self) {
self.chunkify = ::std::option::Option::None;
}
pub fn has_chunkify(&self) -> bool {
self.chunkify.is_some()
}
// Param is passed by value, moved
pub fn set_chunkify(&mut self, v: bool) {
self.chunkify = ::std::option::Option::Some(v);
}
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
let mut fields = ::std::vec::Vec::with_capacity(4);
let mut fields = ::std::vec::Vec::with_capacity(5);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"address",
@ -2682,6 +2740,11 @@ impl VerifyMessage {
|m: &VerifyMessage| { &m.coin_name },
|m: &mut VerifyMessage| { &mut m.coin_name },
));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"chunkify",
|m: &VerifyMessage| { &m.chunkify },
|m: &mut VerifyMessage| { &mut m.chunkify },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<VerifyMessage>(
"VerifyMessage",
fields,
@ -2721,6 +2784,9 @@ impl ::protobuf::Message for VerifyMessage {
34 => {
self.coin_name = ::std::option::Option::Some(is.read_string()?);
},
40 => {
self.chunkify = ::std::option::Option::Some(is.read_bool()?);
},
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@ -2745,6 +2811,9 @@ impl ::protobuf::Message for VerifyMessage {
if let Some(v) = self.coin_name.as_ref() {
my_size += ::protobuf::rt::string_size(4, &v);
}
if let Some(v) = self.chunkify {
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
@ -2763,6 +2832,9 @@ impl ::protobuf::Message for VerifyMessage {
if let Some(v) = self.coin_name.as_ref() {
os.write_string(4, v)?;
}
if let Some(v) = self.chunkify {
os.write_bool(5, v)?;
}
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@ -2784,6 +2856,7 @@ impl ::protobuf::Message for VerifyMessage {
self.signature = ::std::option::Option::None;
self.message = ::std::option::Option::None;
self.coin_name = ::std::option::Option::None;
self.chunkify = ::std::option::Option::None;
self.special_fields.clear();
}
@ -2793,6 +2866,7 @@ impl ::protobuf::Message for VerifyMessage {
signature: ::std::option::Option::None,
message: ::std::option::Option::None,
coin_name: ::std::option::Option::None,
chunkify: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@ -13200,76 +13274,107 @@ static file_descriptor_proto_data: &'static [u8] = b"\
MultisigRedeemScriptTypeR\x08multisig\x12Z\n\x0bscript_type\x18\x04\x20\
\x01(\x0e2+.hw.trezor.messages.bitcoin.InputScriptType:\x0cSPENDADDRESSR\
\nscriptType\"0\n\x0bOwnershipId\x12!\n\x0cownership_id\x18\x01\x20\x02(\
\x0cR\x0bownershipId\"\xec\x01\n\x0bSignMessage\x12\x1b\n\taddress_n\x18\
\x0cR\x0bownershipId\"\x88\x02\n\x0bSignMessage\x12\x1b\n\taddress_n\x18\
\x01\x20\x03(\rR\x08addressN\x12\x18\n\x07message\x18\x02\x20\x02(\x0cR\
\x07message\x12$\n\tcoin_name\x18\x03\x20\x01(\t:\x07BitcoinR\x08coinNam\
e\x12Z\n\x0bscript_type\x18\x04\x20\x01(\x0e2+.hw.trezor.messages.bitcoi\
n.InputScriptType:\x0cSPENDADDRESSR\nscriptType\x12$\n\x0eno_script_type\
\x18\x05\x20\x01(\x08R\x0cnoScriptType\"J\n\x10MessageSignature\x12\x18\
\n\x07address\x18\x01\x20\x02(\tR\x07address\x12\x1c\n\tsignature\x18\
\x02\x20\x02(\x0cR\tsignature\"\x87\x01\n\rVerifyMessage\x12\x18\n\x07ad\
dress\x18\x01\x20\x02(\tR\x07address\x12\x1c\n\tsignature\x18\x02\x20\
\x02(\x0cR\tsignature\x12\x18\n\x07message\x18\x03\x20\x02(\x0cR\x07mess\
age\x12$\n\tcoin_name\x18\x04\x20\x01(\t:\x07BitcoinR\x08coinName\"\xd9\
\x06\n\x06SignTx\x12#\n\routputs_count\x18\x01\x20\x02(\rR\x0coutputsCou\
nt\x12!\n\x0cinputs_count\x18\x02\x20\x02(\rR\x0binputsCount\x12$\n\tcoi\
n_name\x18\x03\x20\x01(\t:\x07BitcoinR\x08coinName\x12\x1b\n\x07version\
\x18\x04\x20\x01(\r:\x011R\x07version\x12\x1e\n\tlock_time\x18\x05\x20\
\x01(\r:\x010R\x08lockTime\x12\x16\n\x06expiry\x18\x06\x20\x01(\rR\x06ex\
piry\x12&\n\x0coverwintered\x18\x07\x20\x01(\x08R\x0coverwinteredB\x02\
\x18\x01\x12(\n\x10version_group_id\x18\x08\x20\x01(\rR\x0eversionGroupI\
d\x12\x1c\n\ttimestamp\x18\t\x20\x01(\rR\ttimestamp\x12\x1b\n\tbranch_id\
\x18\n\x20\x01(\rR\x08branchId\x12P\n\x0bamount_unit\x18\x0b\x20\x01(\
\x0e2&.hw.trezor.messages.bitcoin.AmountUnit:\x07BITCOINR\namountUnit\
\x129\n\x15decred_staking_ticket\x18\x0c\x20\x01(\x08:\x05falseR\x13decr\
edStakingTicket\x12\"\n\tserialize\x18\r\x20\x01(\x08:\x04trueR\tseriali\
ze\x12]\n\x10coinjoin_request\x18\x0e\x20\x01(\x0b22.hw.trezor.messages.\
bitcoin.SignTx.CoinJoinRequestR\x0fcoinjoinRequest\x12\x1a\n\x08chunkify\
\x18\x0f\x20\x01(\x08R\x08chunkify\x1a\xd2\x01\n\x0fCoinJoinRequest\x12\
\x19\n\x08fee_rate\x18\x01\x20\x02(\rR\x07feeRate\x12(\n\x10no_fee_thres\
hold\x18\x02\x20\x02(\x04R\x0enoFeeThreshold\x124\n\x16min_registrable_a\
mount\x18\x03\x20\x02(\x04R\x14minRegistrableAmount\x12&\n\x0fmask_publi\
c_key\x18\x04\x20\x02(\x0cR\rmaskPublicKey\x12\x1c\n\tsignature\x18\x05\
\x20\x02(\x0cR\tsignature\"\xd4\x05\n\tTxRequest\x12T\n\x0crequest_type\
\x18\x01\x20\x01(\x0e21.hw.trezor.messages.bitcoin.TxRequest.RequestType\
R\x0brequestType\x12T\n\x07details\x18\x02\x20\x01(\x0b2:.hw.trezor.mess\
ages.bitcoin.TxRequest.TxRequestDetailsTypeR\x07details\x12]\n\nserializ\
ed\x18\x03\x20\x01(\x0b2=.hw.trezor.messages.bitcoin.TxRequest.TxRequest\
SerializedTypeR\nserialized\x1a\xa6\x01\n\x14TxRequestDetailsType\x12#\n\
\rrequest_index\x18\x01\x20\x01(\rR\x0crequestIndex\x12\x17\n\x07tx_hash\
\x18\x02\x20\x01(\x0cR\x06txHash\x12$\n\x0eextra_data_len\x18\x03\x20\
\x01(\rR\x0cextraDataLen\x12*\n\x11extra_data_offset\x18\x04\x20\x01(\rR\
\x0fextraDataOffset\x1a\x85\x01\n\x17TxRequestSerializedType\x12'\n\x0fs\
ignature_index\x18\x01\x20\x01(\rR\x0esignatureIndex\x12\x1c\n\tsignatur\
e\x18\x02\x20\x01(\x0cR\tsignature\x12#\n\rserialized_tx\x18\x03\x20\x01\
(\x0cR\x0cserializedTx\"\x8a\x01\n\x0bRequestType\x12\x0b\n\x07TXINPUT\
\x10\0\x12\x0c\n\x08TXOUTPUT\x10\x01\x12\n\n\x06TXMETA\x10\x02\x12\x0e\n\
\nTXFINISHED\x10\x03\x12\x0f\n\x0bTXEXTRADATA\x10\x04\x12\x0f\n\x0bTXORI\
GINPUT\x10\x05\x12\x10\n\x0cTXORIGOUTPUT\x10\x06\x12\x10\n\x0cTXPAYMENTR\
EQ\x10\x07\"\xf4\x0f\n\x05TxAck\x12A\n\x02tx\x18\x01\x20\x01(\x0b21.hw.t\
rezor.messages.bitcoin.TxAck.TransactionTypeR\x02tx\x1a\xa3\x0f\n\x0fTra\
nsactionType\x12\x18\n\x07version\x18\x01\x20\x01(\rR\x07version\x12U\n\
\x06inputs\x18\x02\x20\x03(\x0b2=.hw.trezor.messages.bitcoin.TxAck.Trans\
actionType.TxInputTypeR\x06inputs\x12b\n\x0bbin_outputs\x18\x03\x20\x03(\
\x0b2A.hw.trezor.messages.bitcoin.TxAck.TransactionType.TxOutputBinTypeR\
\nbinOutputs\x12\x1b\n\tlock_time\x18\x04\x20\x01(\rR\x08lockTime\x12X\n\
\x07outputs\x18\x05\x20\x03(\x0b2>.hw.trezor.messages.bitcoin.TxAck.Tran\
sactionType.TxOutputTypeR\x07outputs\x12\x1d\n\ninputs_cnt\x18\x06\x20\
\x01(\rR\tinputsCnt\x12\x1f\n\x0boutputs_cnt\x18\x07\x20\x01(\rR\noutput\
sCnt\x12\x1d\n\nextra_data\x18\x08\x20\x01(\x0cR\textraData\x12$\n\x0eex\
tra_data_len\x18\t\x20\x01(\rR\x0cextraDataLen\x12\x16\n\x06expiry\x18\n\
\x20\x01(\rR\x06expiry\x12&\n\x0coverwintered\x18\x0b\x20\x01(\x08R\x0co\
verwinteredB\x02\x18\x01\x12(\n\x10version_group_id\x18\x0c\x20\x01(\rR\
\x0eversionGroupId\x12\x1c\n\ttimestamp\x18\r\x20\x01(\rR\ttimestamp\x12\
\x1b\n\tbranch_id\x18\x0e\x20\x01(\rR\x08branchId\x1a\xf1\x05\n\x0bTxInp\
utType\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x1b\n\tp\
rev_hash\x18\x02\x20\x02(\x0cR\x08prevHash\x12\x1d\n\nprev_index\x18\x03\
\x18\x05\x20\x01(\x08R\x0cnoScriptType\x12\x1a\n\x08chunkify\x18\x06\x20\
\x01(\x08R\x08chunkify\"J\n\x10MessageSignature\x12\x18\n\x07address\x18\
\x01\x20\x02(\tR\x07address\x12\x1c\n\tsignature\x18\x02\x20\x02(\x0cR\t\
signature\"\xa3\x01\n\rVerifyMessage\x12\x18\n\x07address\x18\x01\x20\
\x02(\tR\x07address\x12\x1c\n\tsignature\x18\x02\x20\x02(\x0cR\tsignatur\
e\x12\x18\n\x07message\x18\x03\x20\x02(\x0cR\x07message\x12$\n\tcoin_nam\
e\x18\x04\x20\x01(\t:\x07BitcoinR\x08coinName\x12\x1a\n\x08chunkify\x18\
\x05\x20\x01(\x08R\x08chunkify\"\xd9\x06\n\x06SignTx\x12#\n\routputs_cou\
nt\x18\x01\x20\x02(\rR\x0coutputsCount\x12!\n\x0cinputs_count\x18\x02\
\x20\x02(\rR\x0binputsCount\x12$\n\tcoin_name\x18\x03\x20\x01(\t:\x07Bit\
coinR\x08coinName\x12\x1b\n\x07version\x18\x04\x20\x01(\r:\x011R\x07vers\
ion\x12\x1e\n\tlock_time\x18\x05\x20\x01(\r:\x010R\x08lockTime\x12\x16\n\
\x06expiry\x18\x06\x20\x01(\rR\x06expiry\x12&\n\x0coverwintered\x18\x07\
\x20\x01(\x08R\x0coverwinteredB\x02\x18\x01\x12(\n\x10version_group_id\
\x18\x08\x20\x01(\rR\x0eversionGroupId\x12\x1c\n\ttimestamp\x18\t\x20\
\x01(\rR\ttimestamp\x12\x1b\n\tbranch_id\x18\n\x20\x01(\rR\x08branchId\
\x12P\n\x0bamount_unit\x18\x0b\x20\x01(\x0e2&.hw.trezor.messages.bitcoin\
.AmountUnit:\x07BITCOINR\namountUnit\x129\n\x15decred_staking_ticket\x18\
\x0c\x20\x01(\x08:\x05falseR\x13decredStakingTicket\x12\"\n\tserialize\
\x18\r\x20\x01(\x08:\x04trueR\tserialize\x12]\n\x10coinjoin_request\x18\
\x0e\x20\x01(\x0b22.hw.trezor.messages.bitcoin.SignTx.CoinJoinRequestR\
\x0fcoinjoinRequest\x12\x1a\n\x08chunkify\x18\x0f\x20\x01(\x08R\x08chunk\
ify\x1a\xd2\x01\n\x0fCoinJoinRequest\x12\x19\n\x08fee_rate\x18\x01\x20\
\x02(\rR\x07feeRate\x12(\n\x10no_fee_threshold\x18\x02\x20\x02(\x04R\x0e\
noFeeThreshold\x124\n\x16min_registrable_amount\x18\x03\x20\x02(\x04R\
\x14minRegistrableAmount\x12&\n\x0fmask_public_key\x18\x04\x20\x02(\x0cR\
\rmaskPublicKey\x12\x1c\n\tsignature\x18\x05\x20\x02(\x0cR\tsignature\"\
\xd4\x05\n\tTxRequest\x12T\n\x0crequest_type\x18\x01\x20\x01(\x0e21.hw.t\
rezor.messages.bitcoin.TxRequest.RequestTypeR\x0brequestType\x12T\n\x07d\
etails\x18\x02\x20\x01(\x0b2:.hw.trezor.messages.bitcoin.TxRequest.TxReq\
uestDetailsTypeR\x07details\x12]\n\nserialized\x18\x03\x20\x01(\x0b2=.hw\
.trezor.messages.bitcoin.TxRequest.TxRequestSerializedTypeR\nserialized\
\x1a\xa6\x01\n\x14TxRequestDetailsType\x12#\n\rrequest_index\x18\x01\x20\
\x01(\rR\x0crequestIndex\x12\x17\n\x07tx_hash\x18\x02\x20\x01(\x0cR\x06t\
xHash\x12$\n\x0eextra_data_len\x18\x03\x20\x01(\rR\x0cextraDataLen\x12*\
\n\x11extra_data_offset\x18\x04\x20\x01(\rR\x0fextraDataOffset\x1a\x85\
\x01\n\x17TxRequestSerializedType\x12'\n\x0fsignature_index\x18\x01\x20\
\x01(\rR\x0esignatureIndex\x12\x1c\n\tsignature\x18\x02\x20\x01(\x0cR\ts\
ignature\x12#\n\rserialized_tx\x18\x03\x20\x01(\x0cR\x0cserializedTx\"\
\x8a\x01\n\x0bRequestType\x12\x0b\n\x07TXINPUT\x10\0\x12\x0c\n\x08TXOUTP\
UT\x10\x01\x12\n\n\x06TXMETA\x10\x02\x12\x0e\n\nTXFINISHED\x10\x03\x12\
\x0f\n\x0bTXEXTRADATA\x10\x04\x12\x0f\n\x0bTXORIGINPUT\x10\x05\x12\x10\n\
\x0cTXORIGOUTPUT\x10\x06\x12\x10\n\x0cTXPAYMENTREQ\x10\x07\"\xf4\x0f\n\
\x05TxAck\x12A\n\x02tx\x18\x01\x20\x01(\x0b21.hw.trezor.messages.bitcoin\
.TxAck.TransactionTypeR\x02tx\x1a\xa3\x0f\n\x0fTransactionType\x12\x18\n\
\x07version\x18\x01\x20\x01(\rR\x07version\x12U\n\x06inputs\x18\x02\x20\
\x03(\x0b2=.hw.trezor.messages.bitcoin.TxAck.TransactionType.TxInputType\
R\x06inputs\x12b\n\x0bbin_outputs\x18\x03\x20\x03(\x0b2A.hw.trezor.messa\
ges.bitcoin.TxAck.TransactionType.TxOutputBinTypeR\nbinOutputs\x12\x1b\n\
\tlock_time\x18\x04\x20\x01(\rR\x08lockTime\x12X\n\x07outputs\x18\x05\
\x20\x03(\x0b2>.hw.trezor.messages.bitcoin.TxAck.TransactionType.TxOutpu\
tTypeR\x07outputs\x12\x1d\n\ninputs_cnt\x18\x06\x20\x01(\rR\tinputsCnt\
\x12\x1f\n\x0boutputs_cnt\x18\x07\x20\x01(\rR\noutputsCnt\x12\x1d\n\next\
ra_data\x18\x08\x20\x01(\x0cR\textraData\x12$\n\x0eextra_data_len\x18\t\
\x20\x01(\rR\x0cextraDataLen\x12\x16\n\x06expiry\x18\n\x20\x01(\rR\x06ex\
piry\x12&\n\x0coverwintered\x18\x0b\x20\x01(\x08R\x0coverwinteredB\x02\
\x18\x01\x12(\n\x10version_group_id\x18\x0c\x20\x01(\rR\x0eversionGroupI\
d\x12\x1c\n\ttimestamp\x18\r\x20\x01(\rR\ttimestamp\x12\x1b\n\tbranch_id\
\x18\x0e\x20\x01(\rR\x08branchId\x1a\xf1\x05\n\x0bTxInputType\x12\x1b\n\
\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x1b\n\tprev_hash\x18\x02\
\x20\x02(\x0cR\x08prevHash\x12\x1d\n\nprev_index\x18\x03\x20\x02(\rR\tpr\
evIndex\x12\x1d\n\nscript_sig\x18\x04\x20\x01(\x0cR\tscriptSig\x12&\n\
\x08sequence\x18\x05\x20\x01(\r:\n4294967295R\x08sequence\x12Z\n\x0bscri\
pt_type\x18\x06\x20\x01(\x0e2+.hw.trezor.messages.bitcoin.InputScriptTyp\
e:\x0cSPENDADDRESSR\nscriptType\x12P\n\x08multisig\x18\x07\x20\x01(\x0b2\
4.hw.trezor.messages.bitcoin.MultisigRedeemScriptTypeR\x08multisig\x12\
\x16\n\x06amount\x18\x08\x20\x01(\x04R\x06amount\x12\x1f\n\x0bdecred_tre\
e\x18\t\x20\x01(\rR\ndecredTree\x12\x18\n\x07witness\x18\r\x20\x01(\x0cR\
\x07witness\x12'\n\x0fownership_proof\x18\x0e\x20\x01(\x0cR\x0eownership\
Proof\x12'\n\x0fcommitment_data\x18\x0f\x20\x01(\x0cR\x0ecommitmentData\
\x12\x1b\n\torig_hash\x18\x10\x20\x01(\x0cR\x08origHash\x12\x1d\n\norig_\
index\x18\x11\x20\x01(\rR\torigIndex\x12d\n\x14decred_staking_spend\x18\
\x12\x20\x01(\x0e22.hw.trezor.messages.bitcoin.DecredStakingSpendTypeR\
\x12decredStakingSpend\x12#\n\rscript_pubkey\x18\x13\x20\x01(\x0cR\x0csc\
riptPubkey\x12(\n\x0ecoinjoin_flags\x18\x14\x20\x01(\r:\x010R\rcoinjoinF\
lags\x1a\x82\x01\n\x0fTxOutputBinType\x12\x16\n\x06amount\x18\x01\x20\
\x02(\x04R\x06amount\x12#\n\rscript_pubkey\x18\x02\x20\x02(\x0cR\x0cscri\
ptPubkey\x122\n\x15decred_script_version\x18\x03\x20\x01(\rR\x13decredSc\
riptVersion\x1a\xa0\x03\n\x0cTxOutputType\x12\x18\n\x07address\x18\x01\
\x20\x01(\tR\x07address\x12\x1b\n\taddress_n\x18\x02\x20\x03(\rR\x08addr\
essN\x12\x16\n\x06amount\x18\x03\x20\x02(\x04R\x06amount\x12[\n\x0bscrip\
t_type\x18\x04\x20\x01(\x0e2,.hw.trezor.messages.bitcoin.OutputScriptTyp\
e:\x0cPAYTOADDRESSR\nscriptType\x12P\n\x08multisig\x18\x05\x20\x01(\x0b2\
4.hw.trezor.messages.bitcoin.MultisigRedeemScriptTypeR\x08multisig\x12$\
\n\x0eop_return_data\x18\x06\x20\x01(\x0cR\x0copReturnData\x12\x1b\n\tor\
ig_hash\x18\n\x20\x01(\x0cR\x08origHash\x12\x1d\n\norig_index\x18\x0b\
\x20\x01(\rR\torigIndex\x120\n\x11payment_req_index\x18\x0c\x20\x01(\rR\
\x0fpaymentReqIndexB\x04\xc8\xf0\x19\x01:\x02\x18\x01\"\xff\x05\n\x07TxI\
nput\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x1b\n\tpre\
v_hash\x18\x02\x20\x02(\x0cR\x08prevHash\x12\x1d\n\nprev_index\x18\x03\
\x20\x02(\rR\tprevIndex\x12\x1d\n\nscript_sig\x18\x04\x20\x01(\x0cR\tscr\
iptSig\x12&\n\x08sequence\x18\x05\x20\x01(\r:\n4294967295R\x08sequence\
\x12Z\n\x0bscript_type\x18\x06\x20\x01(\x0e2+.hw.trezor.messages.bitcoin\
.InputScriptType:\x0cSPENDADDRESSR\nscriptType\x12P\n\x08multisig\x18\
\x07\x20\x01(\x0b24.hw.trezor.messages.bitcoin.MultisigRedeemScriptTypeR\
\x08multisig\x12\x16\n\x06amount\x18\x08\x20\x01(\x04R\x06amount\x12\x1f\
\x08multisig\x12\x16\n\x06amount\x18\x08\x20\x02(\x04R\x06amount\x12\x1f\
\n\x0bdecred_tree\x18\t\x20\x01(\rR\ndecredTree\x12\x18\n\x07witness\x18\
\r\x20\x01(\x0cR\x07witness\x12'\n\x0fownership_proof\x18\x0e\x20\x01(\
\x0cR\x0eownershipProof\x12'\n\x0fcommitment_data\x18\x0f\x20\x01(\x0cR\
@ -13278,134 +13383,105 @@ static file_descriptor_proto_data: &'static [u8] = b"\
staking_spend\x18\x12\x20\x01(\x0e22.hw.trezor.messages.bitcoin.DecredSt\
akingSpendTypeR\x12decredStakingSpend\x12#\n\rscript_pubkey\x18\x13\x20\
\x01(\x0cR\x0cscriptPubkey\x12(\n\x0ecoinjoin_flags\x18\x14\x20\x01(\r:\
\x010R\rcoinjoinFlags\x1a\x82\x01\n\x0fTxOutputBinType\x12\x16\n\x06amou\
nt\x18\x01\x20\x02(\x04R\x06amount\x12#\n\rscript_pubkey\x18\x02\x20\x02\
(\x0cR\x0cscriptPubkey\x122\n\x15decred_script_version\x18\x03\x20\x01(\
\rR\x13decredScriptVersion\x1a\xa0\x03\n\x0cTxOutputType\x12\x18\n\x07ad\
dress\x18\x01\x20\x01(\tR\x07address\x12\x1b\n\taddress_n\x18\x02\x20\
\x03(\rR\x08addressN\x12\x16\n\x06amount\x18\x03\x20\x02(\x04R\x06amount\
\x12[\n\x0bscript_type\x18\x04\x20\x01(\x0e2,.hw.trezor.messages.bitcoin\
.OutputScriptType:\x0cPAYTOADDRESSR\nscriptType\x12P\n\x08multisig\x18\
\x05\x20\x01(\x0b24.hw.trezor.messages.bitcoin.MultisigRedeemScriptTypeR\
\x08multisig\x12$\n\x0eop_return_data\x18\x06\x20\x01(\x0cR\x0copReturnD\
ata\x12\x1b\n\torig_hash\x18\n\x20\x01(\x0cR\x08origHash\x12\x1d\n\norig\
_index\x18\x0b\x20\x01(\rR\torigIndex\x120\n\x11payment_req_index\x18\
\x0c\x20\x01(\rR\x0fpaymentReqIndexB\x04\xc8\xf0\x19\x01:\x02\x18\x01\"\
\xff\x05\n\x07TxInput\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addres\
sN\x12\x1b\n\tprev_hash\x18\x02\x20\x02(\x0cR\x08prevHash\x12\x1d\n\npre\
v_index\x18\x03\x20\x02(\rR\tprevIndex\x12\x1d\n\nscript_sig\x18\x04\x20\
\x01(\x0cR\tscriptSig\x12&\n\x08sequence\x18\x05\x20\x01(\r:\n4294967295\
R\x08sequence\x12Z\n\x0bscript_type\x18\x06\x20\x01(\x0e2+.hw.trezor.mes\
sages.bitcoin.InputScriptType:\x0cSPENDADDRESSR\nscriptType\x12P\n\x08mu\
ltisig\x18\x07\x20\x01(\x0b24.hw.trezor.messages.bitcoin.MultisigRedeemS\
criptTypeR\x08multisig\x12\x16\n\x06amount\x18\x08\x20\x02(\x04R\x06amou\
nt\x12\x1f\n\x0bdecred_tree\x18\t\x20\x01(\rR\ndecredTree\x12\x18\n\x07w\
itness\x18\r\x20\x01(\x0cR\x07witness\x12'\n\x0fownership_proof\x18\x0e\
\x20\x01(\x0cR\x0eownershipProof\x12'\n\x0fcommitment_data\x18\x0f\x20\
\x01(\x0cR\x0ecommitmentData\x12\x1b\n\torig_hash\x18\x10\x20\x01(\x0cR\
\x08origHash\x12\x1d\n\norig_index\x18\x11\x20\x01(\rR\torigIndex\x12d\n\
\x14decred_staking_spend\x18\x12\x20\x01(\x0e22.hw.trezor.messages.bitco\
in.DecredStakingSpendTypeR\x12decredStakingSpend\x12#\n\rscript_pubkey\
\x18\x13\x20\x01(\x0cR\x0cscriptPubkey\x12(\n\x0ecoinjoin_flags\x18\x14\
\x20\x01(\r:\x010R\rcoinjoinFlagsJ\x04\x08\n\x10\x0bJ\x04\x08\x0b\x10\
\x0cJ\x04\x08\x0c\x10\r\"\xae\x03\n\x08TxOutput\x12\x18\n\x07address\x18\
\x01\x20\x01(\tR\x07address\x12\x1b\n\taddress_n\x18\x02\x20\x03(\rR\x08\
addressN\x12\x16\n\x06amount\x18\x03\x20\x02(\x04R\x06amount\x12[\n\x0bs\
cript_type\x18\x04\x20\x01(\x0e2,.hw.trezor.messages.bitcoin.OutputScrip\
tType:\x0cPAYTOADDRESSR\nscriptType\x12P\n\x08multisig\x18\x05\x20\x01(\
\x0b24.hw.trezor.messages.bitcoin.MultisigRedeemScriptTypeR\x08multisig\
\x12$\n\x0eop_return_data\x18\x06\x20\x01(\x0cR\x0copReturnData\x12\x1b\
\n\torig_hash\x18\n\x20\x01(\x0cR\x08origHash\x12\x1d\n\norig_index\x18\
\x0b\x20\x01(\rR\torigIndex\x120\n\x11payment_req_index\x18\x0c\x20\x01(\
\rR\x0fpaymentReqIndexB\x04\xc8\xf0\x19\x01J\x04\x08\x07\x10\x08J\x04\
\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xcb\x02\n\x06PrevTx\x12\x18\n\x07versi\
on\x18\x01\x20\x02(\rR\x07version\x12\x1b\n\tlock_time\x18\x04\x20\x02(\
\rR\x08lockTime\x12!\n\x0cinputs_count\x18\x06\x20\x02(\rR\x0binputsCoun\
t\x12#\n\routputs_count\x18\x07\x20\x02(\rR\x0coutputsCount\x12'\n\x0eex\
tra_data_len\x18\t\x20\x01(\r:\x010R\x0cextraDataLen\x12\x16\n\x06expiry\
\x18\n\x20\x01(\rR\x06expiry\x12(\n\x10version_group_id\x18\x0c\x20\x01(\
\rR\x0eversionGroupId\x12\x1c\n\ttimestamp\x18\r\x20\x01(\rR\ttimestamp\
\x12\x1b\n\tbranch_id\x18\x0e\x20\x01(\rR\x08branchIdJ\x04\x08\x02\x10\
\x03J\x04\x08\x03\x10\x04J\x04\x08\x05\x10\x06J\x04\x08\x08\x10\tJ\x04\
\x08\x0b\x10\x0c\"\xf7\x01\n\tPrevInput\x12\x1b\n\tprev_hash\x18\x02\x20\
\x02(\x0cR\x08prevHash\x12\x1d\n\nprev_index\x18\x03\x20\x02(\rR\tprevIn\
dex\x12\x1d\n\nscript_sig\x18\x04\x20\x02(\x0cR\tscriptSig\x12\x1a\n\x08\
sequence\x18\x05\x20\x02(\rR\x08sequence\x12\x1f\n\x0bdecred_tree\x18\t\
\x20\x01(\rR\ndecredTreeJ\x04\x08\x01\x10\x02J\x04\x08\x06\x10\x07J\x04\
\x08\x07\x10\x08J\x04\x08\x08\x10\tJ\x04\x08\n\x10\x0bJ\x04\x08\x0b\x10\
\x0cJ\x04\x08\x0c\x10\rJ\x04\x08\r\x10\x0eJ\x04\x08\x0e\x10\x0fJ\x04\x08\
\x0f\x10\x10J\x04\x08\x10\x10\x11J\x04\x08\x11\x10\x12J\x04\x08\x12\x10\
\x13J\x04\x08\x13\x10\x14\"}\n\nPrevOutput\x12\x16\n\x06amount\x18\x01\
\x20\x02(\x04R\x06amount\x12#\n\rscript_pubkey\x18\x02\x20\x02(\x0cR\x0c\
scriptPubkey\x122\n\x15decred_script_version\x18\x03\x20\x01(\rR\x13decr\
edScriptVersion\"\xf2\x05\n\x13TxAckPaymentRequest\x12\x14\n\x05nonce\
\x18\x01\x20\x01(\x0cR\x05nonce\x12%\n\x0erecipient_name\x18\x02\x20\x02\
(\tR\rrecipientName\x12X\n\x05memos\x18\x03\x20\x03(\x0b2B.hw.trezor.mes\
sages.bitcoin.TxAckPaymentRequest.PaymentRequestMemoR\x05memos\x12\x16\n\
\x06amount\x18\x04\x20\x01(\x04R\x06amount\x12\x1c\n\tsignature\x18\x05\
\x20\x02(\x0cR\tsignature\x1a\xb8\x02\n\x12PaymentRequestMemo\x12U\n\tte\
xt_memo\x18\x01\x20\x01(\x0b28.hw.trezor.messages.bitcoin.TxAckPaymentRe\
quest.TextMemoR\x08textMemo\x12[\n\x0brefund_memo\x18\x02\x20\x01(\x0b2:\
.hw.trezor.messages.bitcoin.TxAckPaymentRequest.RefundMemoR\nrefundMemo\
\x12n\n\x12coin_purchase_memo\x18\x03\x20\x01(\x0b2@.hw.trezor.messages.\
bitcoin.TxAckPaymentRequest.CoinPurchaseMemoR\x10coinPurchaseMemo\x1a\
\x1e\n\x08TextMemo\x12\x12\n\x04text\x18\x01\x20\x02(\tR\x04text\x1a8\n\
\nRefundMemo\x12\x18\n\x07address\x18\x01\x20\x02(\tR\x07address\x12\x10\
\n\x03mac\x18\x02\x20\x02(\x0cR\x03mac\x1as\n\x10CoinPurchaseMemo\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\x10\n\x03mac\x18\x04\x20\x02(\x0cR\x03mac:\x04\x88\xb2\
\x19\x01\"\xac\x01\n\nTxAckInput\x12H\n\x02tx\x18\x01\x20\x02(\x0b28.hw.\
trezor.messages.bitcoin.TxAckInput.TxAckInputWrapperR\x02tx\x1aN\n\x11Tx\
AckInputWrapper\x129\n\x05input\x18\x02\x20\x02(\x0b2#.hw.trezor.message\
s.bitcoin.TxInputR\x05input:\x04\x90\xb2\x19\x16\"\xb3\x01\n\x0bTxAckOut\
put\x12J\n\x02tx\x18\x01\x20\x02(\x0b2:.hw.trezor.messages.bitcoin.TxAck\
Output.TxAckOutputWrapperR\x02tx\x1aR\n\x12TxAckOutputWrapper\x12<\n\x06\
output\x18\x05\x20\x02(\x0b2$.hw.trezor.messages.bitcoin.TxOutputR\x06ou\
tput:\x04\x90\xb2\x19\x16\"I\n\rTxAckPrevMeta\x122\n\x02tx\x18\x01\x20\
\x02(\x0b2\".hw.trezor.messages.bitcoin.PrevTxR\x02tx:\x04\x90\xb2\x19\
\x16\"\xbe\x01\n\x0eTxAckPrevInput\x12P\n\x02tx\x18\x01\x20\x02(\x0b2@.h\
w.trezor.messages.bitcoin.TxAckPrevInput.TxAckPrevInputWrapperR\x02tx\
\x1aT\n\x15TxAckPrevInputWrapper\x12;\n\x05input\x18\x02\x20\x02(\x0b2%.\
hw.trezor.messages.bitcoin.PrevInputR\x05input:\x04\x90\xb2\x19\x16\"\
\xc5\x01\n\x0fTxAckPrevOutput\x12R\n\x02tx\x18\x01\x20\x02(\x0b2B.hw.tre\
zor.messages.bitcoin.TxAckPrevOutput.TxAckPrevOutputWrapperR\x02tx\x1aX\
\n\x16TxAckPrevOutputWrapper\x12>\n\x06output\x18\x03\x20\x02(\x0b2&.hw.\
trezor.messages.bitcoin.PrevOutputR\x06output:\x04\x90\xb2\x19\x16\"\xbb\
\x01\n\x12TxAckPrevExtraData\x12X\n\x02tx\x18\x01\x20\x02(\x0b2H.hw.trez\
or.messages.bitcoin.TxAckPrevExtraData.TxAckPrevExtraDataWrapperR\x02tx\
\x1aE\n\x19TxAckPrevExtraDataWrapper\x12(\n\x10extra_data_chunk\x18\x08\
\x20\x02(\x0cR\x0eextraDataChunk:\x04\x90\xb2\x19\x16\"\x88\x03\n\x11Get\
OwnershipProof\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12$\
\n\tcoin_name\x18\x02\x20\x01(\t:\x07BitcoinR\x08coinName\x12Z\n\x0bscri\
pt_type\x18\x03\x20\x01(\x0e2+.hw.trezor.messages.bitcoin.InputScriptTyp\
e:\x0cSPENDWITNESSR\nscriptType\x12P\n\x08multisig\x18\x04\x20\x01(\x0b2\
4.hw.trezor.messages.bitcoin.MultisigRedeemScriptTypeR\x08multisig\x122\
\n\x11user_confirmation\x18\x05\x20\x01(\x08:\x05falseR\x10userConfirmat\
ion\x12#\n\rownership_ids\x18\x06\x20\x03(\x0cR\x0cownershipIds\x12)\n\
\x0fcommitment_data\x18\x07\x20\x01(\x0c:\0R\x0ecommitmentData\"W\n\x0eO\
wnershipProof\x12'\n\x0fownership_proof\x18\x01\x20\x02(\x0cR\x0eownersh\
ipProof\x12\x1c\n\tsignature\x18\x02\x20\x02(\x0cR\tsignature\"\xab\x03\
\n\x11AuthorizeCoinJoin\x12\x20\n\x0bcoordinator\x18\x01\x20\x02(\tR\x0b\
coordinator\x12\x1d\n\nmax_rounds\x18\x02\x20\x02(\x04R\tmaxRounds\x127\
\n\x18max_coordinator_fee_rate\x18\x03\x20\x02(\rR\x15maxCoordinatorFeeR\
ate\x12+\n\x12max_fee_per_kvbyte\x18\x04\x20\x02(\rR\x0fmaxFeePerKvbyte\
\x12\x1b\n\taddress_n\x18\x05\x20\x03(\rR\x08addressN\x12$\n\tcoin_name\
\x18\x06\x20\x01(\t:\x07BitcoinR\x08coinName\x12Z\n\x0bscript_type\x18\
\x07\x20\x01(\x0e2+.hw.trezor.messages.bitcoin.InputScriptType:\x0cSPEND\
ADDRESSR\nscriptType\x12P\n\x0bamount_unit\x18\x08\x20\x01(\x0e2&.hw.tre\
zor.messages.bitcoin.AmountUnit:\x07BITCOINR\namountUnit*~\n\x0fInputScr\
iptType\x12\x10\n\x0cSPENDADDRESS\x10\0\x12\x11\n\rSPENDMULTISIG\x10\x01\
\x12\x0c\n\x08EXTERNAL\x10\x02\x12\x10\n\x0cSPENDWITNESS\x10\x03\x12\x14\
\n\x10SPENDP2SHWITNESS\x10\x04\x12\x10\n\x0cSPENDTAPROOT\x10\x05*\x99\
\x01\n\x10OutputScriptType\x12\x10\n\x0cPAYTOADDRESS\x10\0\x12\x13\n\x0f\
PAYTOSCRIPTHASH\x10\x01\x12\x11\n\rPAYTOMULTISIG\x10\x02\x12\x11\n\rPAYT\
OOPRETURN\x10\x03\x12\x10\n\x0cPAYTOWITNESS\x10\x04\x12\x14\n\x10PAYTOP2\
SHWITNESS\x10\x05\x12\x10\n\x0cPAYTOTAPROOT\x10\x06*.\n\x16DecredStaking\
SpendType\x12\t\n\x05SSGen\x10\0\x12\t\n\x05SSRTX\x10\x01*J\n\nAmountUni\
t\x12\x0b\n\x07BITCOIN\x10\0\x12\x10\n\x0cMILLIBITCOIN\x10\x01\x12\x10\n\
\x0cMICROBITCOIN\x10\x02\x12\x0b\n\x07SATOSHI\x10\x03B?\n#com.satoshilab\
s.trezor.lib.protobufB\x14TrezorMessageBitcoin\x80\xa6\x1d\x01\
\x010R\rcoinjoinFlagsJ\x04\x08\n\x10\x0bJ\x04\x08\x0b\x10\x0cJ\x04\x08\
\x0c\x10\r\"\xae\x03\n\x08TxOutput\x12\x18\n\x07address\x18\x01\x20\x01(\
\tR\x07address\x12\x1b\n\taddress_n\x18\x02\x20\x03(\rR\x08addressN\x12\
\x16\n\x06amount\x18\x03\x20\x02(\x04R\x06amount\x12[\n\x0bscript_type\
\x18\x04\x20\x01(\x0e2,.hw.trezor.messages.bitcoin.OutputScriptType:\x0c\
PAYTOADDRESSR\nscriptType\x12P\n\x08multisig\x18\x05\x20\x01(\x0b24.hw.t\
rezor.messages.bitcoin.MultisigRedeemScriptTypeR\x08multisig\x12$\n\x0eo\
p_return_data\x18\x06\x20\x01(\x0cR\x0copReturnData\x12\x1b\n\torig_hash\
\x18\n\x20\x01(\x0cR\x08origHash\x12\x1d\n\norig_index\x18\x0b\x20\x01(\
\rR\torigIndex\x120\n\x11payment_req_index\x18\x0c\x20\x01(\rR\x0fpaymen\
tReqIndexB\x04\xc8\xf0\x19\x01J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\tJ\
\x04\x08\t\x10\n\"\xcb\x02\n\x06PrevTx\x12\x18\n\x07version\x18\x01\x20\
\x02(\rR\x07version\x12\x1b\n\tlock_time\x18\x04\x20\x02(\rR\x08lockTime\
\x12!\n\x0cinputs_count\x18\x06\x20\x02(\rR\x0binputsCount\x12#\n\routpu\
ts_count\x18\x07\x20\x02(\rR\x0coutputsCount\x12'\n\x0eextra_data_len\
\x18\t\x20\x01(\r:\x010R\x0cextraDataLen\x12\x16\n\x06expiry\x18\n\x20\
\x01(\rR\x06expiry\x12(\n\x10version_group_id\x18\x0c\x20\x01(\rR\x0ever\
sionGroupId\x12\x1c\n\ttimestamp\x18\r\x20\x01(\rR\ttimestamp\x12\x1b\n\
\tbranch_id\x18\x0e\x20\x01(\rR\x08branchIdJ\x04\x08\x02\x10\x03J\x04\
\x08\x03\x10\x04J\x04\x08\x05\x10\x06J\x04\x08\x08\x10\tJ\x04\x08\x0b\
\x10\x0c\"\xf7\x01\n\tPrevInput\x12\x1b\n\tprev_hash\x18\x02\x20\x02(\
\x0cR\x08prevHash\x12\x1d\n\nprev_index\x18\x03\x20\x02(\rR\tprevIndex\
\x12\x1d\n\nscript_sig\x18\x04\x20\x02(\x0cR\tscriptSig\x12\x1a\n\x08seq\
uence\x18\x05\x20\x02(\rR\x08sequence\x12\x1f\n\x0bdecred_tree\x18\t\x20\
\x01(\rR\ndecredTreeJ\x04\x08\x01\x10\x02J\x04\x08\x06\x10\x07J\x04\x08\
\x07\x10\x08J\x04\x08\x08\x10\tJ\x04\x08\n\x10\x0bJ\x04\x08\x0b\x10\x0cJ\
\x04\x08\x0c\x10\rJ\x04\x08\r\x10\x0eJ\x04\x08\x0e\x10\x0fJ\x04\x08\x0f\
\x10\x10J\x04\x08\x10\x10\x11J\x04\x08\x11\x10\x12J\x04\x08\x12\x10\x13J\
\x04\x08\x13\x10\x14\"}\n\nPrevOutput\x12\x16\n\x06amount\x18\x01\x20\
\x02(\x04R\x06amount\x12#\n\rscript_pubkey\x18\x02\x20\x02(\x0cR\x0cscri\
ptPubkey\x122\n\x15decred_script_version\x18\x03\x20\x01(\rR\x13decredSc\
riptVersion\"\xf2\x05\n\x13TxAckPaymentRequest\x12\x14\n\x05nonce\x18\
\x01\x20\x01(\x0cR\x05nonce\x12%\n\x0erecipient_name\x18\x02\x20\x02(\tR\
\rrecipientName\x12X\n\x05memos\x18\x03\x20\x03(\x0b2B.hw.trezor.message\
s.bitcoin.TxAckPaymentRequest.PaymentRequestMemoR\x05memos\x12\x16\n\x06\
amount\x18\x04\x20\x01(\x04R\x06amount\x12\x1c\n\tsignature\x18\x05\x20\
\x02(\x0cR\tsignature\x1a\xb8\x02\n\x12PaymentRequestMemo\x12U\n\ttext_m\
emo\x18\x01\x20\x01(\x0b28.hw.trezor.messages.bitcoin.TxAckPaymentReques\
t.TextMemoR\x08textMemo\x12[\n\x0brefund_memo\x18\x02\x20\x01(\x0b2:.hw.\
trezor.messages.bitcoin.TxAckPaymentRequest.RefundMemoR\nrefundMemo\x12n\
\n\x12coin_purchase_memo\x18\x03\x20\x01(\x0b2@.hw.trezor.messages.bitco\
in.TxAckPaymentRequest.CoinPurchaseMemoR\x10coinPurchaseMemo\x1a\x1e\n\
\x08TextMemo\x12\x12\n\x04text\x18\x01\x20\x02(\tR\x04text\x1a8\n\nRefun\
dMemo\x12\x18\n\x07address\x18\x01\x20\x02(\tR\x07address\x12\x10\n\x03m\
ac\x18\x02\x20\x02(\x0cR\x03mac\x1as\n\x10CoinPurchaseMemo\x12\x1b\n\tco\
in_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\x10\n\x03mac\x18\x04\x20\x02(\x0cR\x03mac:\x04\x88\xb2\x19\x01\"\
\xac\x01\n\nTxAckInput\x12H\n\x02tx\x18\x01\x20\x02(\x0b28.hw.trezor.mes\
sages.bitcoin.TxAckInput.TxAckInputWrapperR\x02tx\x1aN\n\x11TxAckInputWr\
apper\x129\n\x05input\x18\x02\x20\x02(\x0b2#.hw.trezor.messages.bitcoin.\
TxInputR\x05input:\x04\x90\xb2\x19\x16\"\xb3\x01\n\x0bTxAckOutput\x12J\n\
\x02tx\x18\x01\x20\x02(\x0b2:.hw.trezor.messages.bitcoin.TxAckOutput.TxA\
ckOutputWrapperR\x02tx\x1aR\n\x12TxAckOutputWrapper\x12<\n\x06output\x18\
\x05\x20\x02(\x0b2$.hw.trezor.messages.bitcoin.TxOutputR\x06output:\x04\
\x90\xb2\x19\x16\"I\n\rTxAckPrevMeta\x122\n\x02tx\x18\x01\x20\x02(\x0b2\
\".hw.trezor.messages.bitcoin.PrevTxR\x02tx:\x04\x90\xb2\x19\x16\"\xbe\
\x01\n\x0eTxAckPrevInput\x12P\n\x02tx\x18\x01\x20\x02(\x0b2@.hw.trezor.m\
essages.bitcoin.TxAckPrevInput.TxAckPrevInputWrapperR\x02tx\x1aT\n\x15Tx\
AckPrevInputWrapper\x12;\n\x05input\x18\x02\x20\x02(\x0b2%.hw.trezor.mes\
sages.bitcoin.PrevInputR\x05input:\x04\x90\xb2\x19\x16\"\xc5\x01\n\x0fTx\
AckPrevOutput\x12R\n\x02tx\x18\x01\x20\x02(\x0b2B.hw.trezor.messages.bit\
coin.TxAckPrevOutput.TxAckPrevOutputWrapperR\x02tx\x1aX\n\x16TxAckPrevOu\
tputWrapper\x12>\n\x06output\x18\x03\x20\x02(\x0b2&.hw.trezor.messages.b\
itcoin.PrevOutputR\x06output:\x04\x90\xb2\x19\x16\"\xbb\x01\n\x12TxAckPr\
evExtraData\x12X\n\x02tx\x18\x01\x20\x02(\x0b2H.hw.trezor.messages.bitco\
in.TxAckPrevExtraData.TxAckPrevExtraDataWrapperR\x02tx\x1aE\n\x19TxAckPr\
evExtraDataWrapper\x12(\n\x10extra_data_chunk\x18\x08\x20\x02(\x0cR\x0ee\
xtraDataChunk:\x04\x90\xb2\x19\x16\"\x88\x03\n\x11GetOwnershipProof\x12\
\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12$\n\tcoin_name\x18\
\x02\x20\x01(\t:\x07BitcoinR\x08coinName\x12Z\n\x0bscript_type\x18\x03\
\x20\x01(\x0e2+.hw.trezor.messages.bitcoin.InputScriptType:\x0cSPENDWITN\
ESSR\nscriptType\x12P\n\x08multisig\x18\x04\x20\x01(\x0b24.hw.trezor.mes\
sages.bitcoin.MultisigRedeemScriptTypeR\x08multisig\x122\n\x11user_confi\
rmation\x18\x05\x20\x01(\x08:\x05falseR\x10userConfirmation\x12#\n\rowne\
rship_ids\x18\x06\x20\x03(\x0cR\x0cownershipIds\x12)\n\x0fcommitment_dat\
a\x18\x07\x20\x01(\x0c:\0R\x0ecommitmentData\"W\n\x0eOwnershipProof\x12'\
\n\x0fownership_proof\x18\x01\x20\x02(\x0cR\x0eownershipProof\x12\x1c\n\
\tsignature\x18\x02\x20\x02(\x0cR\tsignature\"\xab\x03\n\x11AuthorizeCoi\
nJoin\x12\x20\n\x0bcoordinator\x18\x01\x20\x02(\tR\x0bcoordinator\x12\
\x1d\n\nmax_rounds\x18\x02\x20\x02(\x04R\tmaxRounds\x127\n\x18max_coordi\
nator_fee_rate\x18\x03\x20\x02(\rR\x15maxCoordinatorFeeRate\x12+\n\x12ma\
x_fee_per_kvbyte\x18\x04\x20\x02(\rR\x0fmaxFeePerKvbyte\x12\x1b\n\taddre\
ss_n\x18\x05\x20\x03(\rR\x08addressN\x12$\n\tcoin_name\x18\x06\x20\x01(\
\t:\x07BitcoinR\x08coinName\x12Z\n\x0bscript_type\x18\x07\x20\x01(\x0e2+\
.hw.trezor.messages.bitcoin.InputScriptType:\x0cSPENDADDRESSR\nscriptTyp\
e\x12P\n\x0bamount_unit\x18\x08\x20\x01(\x0e2&.hw.trezor.messages.bitcoi\
n.AmountUnit:\x07BITCOINR\namountUnit*~\n\x0fInputScriptType\x12\x10\n\
\x0cSPENDADDRESS\x10\0\x12\x11\n\rSPENDMULTISIG\x10\x01\x12\x0c\n\x08EXT\
ERNAL\x10\x02\x12\x10\n\x0cSPENDWITNESS\x10\x03\x12\x14\n\x10SPENDP2SHWI\
TNESS\x10\x04\x12\x10\n\x0cSPENDTAPROOT\x10\x05*\x99\x01\n\x10OutputScri\
ptType\x12\x10\n\x0cPAYTOADDRESS\x10\0\x12\x13\n\x0fPAYTOSCRIPTHASH\x10\
\x01\x12\x11\n\rPAYTOMULTISIG\x10\x02\x12\x11\n\rPAYTOOPRETURN\x10\x03\
\x12\x10\n\x0cPAYTOWITNESS\x10\x04\x12\x14\n\x10PAYTOP2SHWITNESS\x10\x05\
\x12\x10\n\x0cPAYTOTAPROOT\x10\x06*.\n\x16DecredStakingSpendType\x12\t\n\
\x05SSGen\x10\0\x12\t\n\x05SSRTX\x10\x01*J\n\nAmountUnit\x12\x0b\n\x07BI\
TCOIN\x10\0\x12\x10\n\x0cMILLIBITCOIN\x10\x01\x12\x10\n\x0cMICROBITCOIN\
\x10\x02\x12\x0b\n\x07SATOSHI\x10\x03B?\n#com.satoshilabs.trezor.lib.pro\
tobufB\x14TrezorMessageBitcoin\x80\xa6\x1d\x01\
";
/// `FileDescriptorProto` object which was a source for this generated file

View File

@ -2792,6 +2792,8 @@ pub struct EthereumSignMessage {
pub message: ::std::option::Option<::std::vec::Vec<u8>>,
// @@protoc_insertion_point(field:hw.trezor.messages.ethereum.EthereumSignMessage.encoded_network)
pub encoded_network: ::std::option::Option<::std::vec::Vec<u8>>,
// @@protoc_insertion_point(field:hw.trezor.messages.ethereum.EthereumSignMessage.chunkify)
pub chunkify: ::std::option::Option<bool>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.ethereum.EthereumSignMessage.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@ -2880,8 +2882,27 @@ impl EthereumSignMessage {
self.encoded_network.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
// optional bool chunkify = 4;
pub fn chunkify(&self) -> bool {
self.chunkify.unwrap_or(false)
}
pub fn clear_chunkify(&mut self) {
self.chunkify = ::std::option::Option::None;
}
pub fn has_chunkify(&self) -> bool {
self.chunkify.is_some()
}
// Param is passed by value, moved
pub fn set_chunkify(&mut self, v: bool) {
self.chunkify = ::std::option::Option::Some(v);
}
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_vec_simpler_accessor::<_, _>(
"address_n",
@ -2898,6 +2919,11 @@ impl EthereumSignMessage {
|m: &EthereumSignMessage| { &m.encoded_network },
|m: &mut EthereumSignMessage| { &mut m.encoded_network },
));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"chunkify",
|m: &EthereumSignMessage| { &m.chunkify },
|m: &mut EthereumSignMessage| { &mut m.chunkify },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<EthereumSignMessage>(
"EthereumSignMessage",
fields,
@ -2931,6 +2957,9 @@ impl ::protobuf::Message for EthereumSignMessage {
26 => {
self.encoded_network = ::std::option::Option::Some(is.read_bytes()?);
},
32 => {
self.chunkify = ::std::option::Option::Some(is.read_bool()?);
},
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@ -2952,6 +2981,9 @@ impl ::protobuf::Message for EthereumSignMessage {
if let Some(v) = self.encoded_network.as_ref() {
my_size += ::protobuf::rt::bytes_size(3, &v);
}
if let Some(v) = self.chunkify {
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
@ -2967,6 +2999,9 @@ impl ::protobuf::Message for EthereumSignMessage {
if let Some(v) = self.encoded_network.as_ref() {
os.write_bytes(3, v)?;
}
if let Some(v) = self.chunkify {
os.write_bool(4, v)?;
}
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@ -2987,6 +3022,7 @@ impl ::protobuf::Message for EthereumSignMessage {
self.address_n.clear();
self.message = ::std::option::Option::None;
self.encoded_network = ::std::option::Option::None;
self.chunkify = ::std::option::Option::None;
self.special_fields.clear();
}
@ -2995,6 +3031,7 @@ impl ::protobuf::Message for EthereumSignMessage {
address_n: ::std::vec::Vec::new(),
message: ::std::option::Option::None,
encoded_network: ::std::option::Option::None,
chunkify: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@ -3246,6 +3283,8 @@ pub struct EthereumVerifyMessage {
pub message: ::std::option::Option<::std::vec::Vec<u8>>,
// @@protoc_insertion_point(field:hw.trezor.messages.ethereum.EthereumVerifyMessage.address)
pub address: ::std::option::Option<::std::string::String>,
// @@protoc_insertion_point(field:hw.trezor.messages.ethereum.EthereumVerifyMessage.chunkify)
pub chunkify: ::std::option::Option<bool>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.ethereum.EthereumVerifyMessage.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@ -3370,8 +3409,27 @@ impl EthereumVerifyMessage {
self.address.take().unwrap_or_else(|| ::std::string::String::new())
}
// optional bool chunkify = 5;
pub fn chunkify(&self) -> bool {
self.chunkify.unwrap_or(false)
}
pub fn clear_chunkify(&mut self) {
self.chunkify = ::std::option::Option::None;
}
pub fn has_chunkify(&self) -> bool {
self.chunkify.is_some()
}
// Param is passed by value, moved
pub fn set_chunkify(&mut self, v: bool) {
self.chunkify = ::std::option::Option::Some(v);
}
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_option_accessor::<_, _>(
"signature",
@ -3388,6 +3446,11 @@ impl EthereumVerifyMessage {
|m: &EthereumVerifyMessage| { &m.address },
|m: &mut EthereumVerifyMessage| { &mut m.address },
));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"chunkify",
|m: &EthereumVerifyMessage| { &m.chunkify },
|m: &mut EthereumVerifyMessage| { &mut m.chunkify },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<EthereumVerifyMessage>(
"EthereumVerifyMessage",
fields,
@ -3424,6 +3487,9 @@ impl ::protobuf::Message for EthereumVerifyMessage {
34 => {
self.address = ::std::option::Option::Some(is.read_string()?);
},
40 => {
self.chunkify = ::std::option::Option::Some(is.read_bool()?);
},
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@ -3445,6 +3511,9 @@ impl ::protobuf::Message for EthereumVerifyMessage {
if let Some(v) = self.address.as_ref() {
my_size += ::protobuf::rt::string_size(4, &v);
}
if let Some(v) = self.chunkify {
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
@ -3460,6 +3529,9 @@ impl ::protobuf::Message for EthereumVerifyMessage {
if let Some(v) = self.address.as_ref() {
os.write_string(4, v)?;
}
if let Some(v) = self.chunkify {
os.write_bool(5, v)?;
}
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@ -3480,6 +3552,7 @@ impl ::protobuf::Message for EthereumVerifyMessage {
self.signature = ::std::option::Option::None;
self.message = ::std::option::Option::None;
self.address = ::std::option::Option::None;
self.chunkify = ::std::option::Option::None;
self.special_fields.clear();
}
@ -3488,6 +3561,7 @@ impl ::protobuf::Message for EthereumVerifyMessage {
signature: ::std::option::Option::None,
message: ::std::option::Option::None,
address: ::std::option::Option::None,
chunkify: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@ -4061,22 +4135,23 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x01(\rR\ndataLength\x12\x1f\n\x0bsignature_v\x18\x02\x20\x01(\rR\nsigna\
tureV\x12\x1f\n\x0bsignature_r\x18\x03\x20\x01(\x0cR\nsignatureR\x12\x1f\
\n\x0bsignature_s\x18\x04\x20\x01(\x0cR\nsignatureS\".\n\rEthereumTxAck\
\x12\x1d\n\ndata_chunk\x18\x01\x20\x02(\x0cR\tdataChunk\"u\n\x13Ethereum\
SignMessage\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x18\
\n\x07message\x18\x02\x20\x02(\x0cR\x07message\x12'\n\x0fencoded_network\
\x18\x03\x20\x01(\x0cR\x0eencodedNetwork\"R\n\x18EthereumMessageSignatur\
e\x12\x1c\n\tsignature\x18\x02\x20\x02(\x0cR\tsignature\x12\x18\n\x07add\
ress\x18\x03\x20\x02(\tR\x07address\"i\n\x15EthereumVerifyMessage\x12\
\x12\x1d\n\ndata_chunk\x18\x01\x20\x02(\x0cR\tdataChunk\"\x91\x01\n\x13E\
thereumSignMessage\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\
\x12\x18\n\x07message\x18\x02\x20\x02(\x0cR\x07message\x12'\n\x0fencoded\
_network\x18\x03\x20\x01(\x0cR\x0eencodedNetwork\x12\x1a\n\x08chunkify\
\x18\x04\x20\x01(\x08R\x08chunkify\"R\n\x18EthereumMessageSignature\x12\
\x1c\n\tsignature\x18\x02\x20\x02(\x0cR\tsignature\x12\x18\n\x07address\
\x18\x03\x20\x02(\tR\x07address\"\x85\x01\n\x15EthereumVerifyMessage\x12\
\x1c\n\tsignature\x18\x02\x20\x02(\x0cR\tsignature\x12\x18\n\x07message\
\x18\x03\x20\x02(\x0cR\x07message\x12\x18\n\x07address\x18\x04\x20\x02(\
\tR\x07address\"\xb4\x01\n\x15EthereumSignTypedHash\x12\x1b\n\taddress_n\
\x18\x01\x20\x03(\rR\x08addressN\x122\n\x15domain_separator_hash\x18\x02\
\x20\x02(\x0cR\x13domainSeparatorHash\x12!\n\x0cmessage_hash\x18\x03\x20\
\x01(\x0cR\x0bmessageHash\x12'\n\x0fencoded_network\x18\x04\x20\x01(\x0c\
R\x0eencodedNetwork\"T\n\x1aEthereumTypedDataSignature\x12\x1c\n\tsignat\
ure\x18\x01\x20\x02(\x0cR\tsignature\x12\x18\n\x07address\x18\x02\x20\
\x02(\tR\x07addressB<\n#com.satoshilabs.trezor.lib.protobufB\x15TrezorMe\
ssageEthereum\
\tR\x07address\x12\x1a\n\x08chunkify\x18\x05\x20\x01(\x08R\x08chunkify\"\
\xb4\x01\n\x15EthereumSignTypedHash\x12\x1b\n\taddress_n\x18\x01\x20\x03\
(\rR\x08addressN\x122\n\x15domain_separator_hash\x18\x02\x20\x02(\x0cR\
\x13domainSeparatorHash\x12!\n\x0cmessage_hash\x18\x03\x20\x01(\x0cR\x0b\
messageHash\x12'\n\x0fencoded_network\x18\x04\x20\x01(\x0cR\x0eencodedNe\
twork\"T\n\x1aEthereumTypedDataSignature\x12\x1c\n\tsignature\x18\x01\
\x20\x02(\x0cR\tsignature\x12\x18\n\x07address\x18\x02\x20\x02(\tR\x07ad\
dressB<\n#com.satoshilabs.trezor.lib.protobufB\x15TrezorMessageEthereum\
";
/// `FileDescriptorProto` object which was a source for this generated file

View File

@ -21,9 +21,10 @@ import pytest
from trezorlib import btc, messages
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import message_filters
from trezorlib.exceptions import Cancelled
from trezorlib.tools import parse_path
from ...input_flows import InputFlowSignMessagePagination
from ...input_flows import InputFlowSignMessageInfo, InputFlowSignMessagePagination
S = messages.InputScriptType
@ -303,14 +304,47 @@ def test_signmessage(
assert sig.signature.hex() == signature
@pytest.mark.skip_t1
@pytest.mark.skip_tr
@pytest.mark.parametrize(
"coin_name, path, script_type, no_script_type, address, message, signature", VECTORS
)
def test_signmessage_info(
client: Client,
coin_name: str,
path: str,
script_type: messages.InputScriptType,
no_script_type: bool,
address: str,
message: str,
signature: str,
):
with client, pytest.raises(Cancelled):
IF = InputFlowSignMessageInfo(client)
client.set_input_flow(IF.get())
sig = btc.sign_message(
client,
coin_name=coin_name,
n=parse_path(path),
script_type=script_type,
no_script_type=no_script_type,
message=message,
chunkify=True,
)
assert sig.address == address
assert sig.signature.hex() == signature
MESSAGE_LENGTHS = (
pytest.param("This is a very long message. " * 16, id="normal_text"),
pytest.param("ThisIsAMessageWithoutSpaces" * 16, id="no_spaces"),
pytest.param("ThisIsAMessageWithLongWords " * 16, id="long_words"),
pytest.param("This\nmessage\nhas\nnewlines\nafter\nevery\nword", id="newlines"),
pytest.param(
"This\nmessage\nhas\nnewlines\nafter\nevery\nsingle\nword", id="newlines"
),
pytest.param("Příšerně žluťoučký kůň úpěl ďábelské ódy. " * 16, id="utf_text"),
pytest.param("PříšerněŽluťoučkýKůňÚpělĎábelskéÓdy" * 16, id="utf_nospace"),
pytest.param("1\n2\n3\n4\n5\n6", id="single_line_over"),
pytest.param("1\n2\n3\n4\n5\n6\n7", id="single_line_over"),
)
@ -330,9 +364,7 @@ def test_signmessage_pagination(client: Client, message: str):
# We cannot differentiate between a newline and space in the message read from Trezor.
# TODO: do the check also for model R
if client.features.model == "T":
expected_message = (
("Confirm message: " + message).replace("\n", "").replace(" ", "")
)
expected_message = message.replace("\n", "").replace(" ", "")
message_read = IF.message_read.replace(" ", "").replace("...", "")
assert expected_message == message_read
@ -340,7 +372,7 @@ def test_signmessage_pagination(client: Client, message: str):
@pytest.mark.skip_t1
@pytest.mark.skip_tr(reason="Different screen size")
def test_signmessage_pagination_trailing_newline(client: Client):
message = "THIS\nMUST NOT\nBE\nPAGINATED\n"
message = "THIS\nMUST\nNOT\nBE\nPAGINATED\n"
# The trailing newline must not cause a new paginated screen to appear.
# The UI must be a single dialog without pagination.
with client:

View File

@ -254,6 +254,28 @@ class InputFlowSignMessagePagination(InputFlowBase):
self.debug.press_yes()
class InputFlowSignMessageInfo(InputFlowBase):
def __init__(self, client: Client):
super().__init__(client)
def input_flow_tt(self) -> BRGeneratorType:
yield
# show address/message info
self.debug.click(buttons.CORNER_BUTTON, wait=True)
self.debug.click(buttons.CORNER_BUTTON, wait=True)
self.debug.press_no(wait=True)
self.debug.synchronize_at("mismatch")
# address mismatch?
self.debug.press_no()
yield
self.debug.press_yes()
yield
self.debug.press_no()
yield
self.debug.press_no(wait=True)
self.debug.press_yes(wait=True)
class InputFlowShowAddressQRCode(InputFlowBase):
def __init__(self, client: Client):
super().__init__(client)

View File

@ -1045,10 +1045,10 @@
"TR_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh2]": "98dac05a444553eb733f4ebb76a83d5310f35f1d57f7613909671d02cb62bbd4",
"TR_bitcoin-test_signmessage.py::test_signmessage[t1 firmware path]": "e1c8b0b2a0feff6256cd985cdf7abbcb68c0d76ebc1141758c5821c4bc5bde69",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[long_words]": "50bc1025b2d98048506b79cbb4c9a7afb77f4c6dff869448d3ea16e44e482cb1",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[newlines]": "28562281b4ab4850735823916d9ea365a5611f4beca9b979fbae4cfc3bf5a895",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[newlines]": "149cdc0a68dfa52c858ba71e8d0004f8324721182831eb4c4f73005d195f770f",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[no_spaces]": "e4ba6c1f03f69753fbdd0b3f6f48d5cb4668f9f0e46171f5cede04535093017e",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[normal_text]": "11b09fc1f623f522e4ece098051385438adb8483dce4e77977bc458a7c6d3db6",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[single_line_over]": "b204b1920ddc1b0a475d7a4e1f8721338090769af26a23f874e309a654de60cf",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[single_line_over]": "bd588c72a241b81894f074b28b7dfaa9c20bf36b6eddb78687f8f54637912410",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_nospace]": "4845ed702d5bb635a15b412d91951c2c46ea00754b4aa9fe08c50f287608d345",
"TR_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_text]": "6aaa568ba69cd2da4df0821e0b640e93669f9753531327bbda42acca23d56207",
"TR_bitcoin-test_signmessage.py::test_signmessage_path_warning": "73d55c948994957a7af2aeb2927657fe39b1f1f5db35075b246512a4cc695242",
@ -2300,11 +2300,11 @@
"TT_bitcoin-test_nonstandard_paths.py::test_getpublicnode[m-3h-100h-4-255-script_types1]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_bitcoin-test_nonstandard_paths.py::test_getpublicnode[m-4-255-script_types0]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_bitcoin-test_nonstandard_paths.py::test_getpublicnode[m-49-0-63-0-255-script_types4]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-1195487518-6-255-script_types3]": "f5e5824dcb02e87560c883a0327fdc8c37e5aad85360eda53d5af76596f97bf3",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-1195487518-script_types2]": "60beb81aef398d358459f57b33f7e231427d58e7b6d1e496c54235d8c770c7bd",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-3h-100h-4-255-script_types1]": "6b9494bc08eb3afd8612e6beb0bfaa57afff7c8dcb280e26acd523b979b12fc6",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-4-255-script_types0]": "28709fd0bbf3dcca4fcc6a07b6b0259a8f44d1b3bde3b0188f248b2659950019",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-49-0-63-0-255-script_types4]": "4b775c3b06b33a790774f7cd189b9ff6dcf16fe5a7d4bcccb970ac5f2cfff531",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-1195487518-6-255-script_types3]": "c8dcc2856fc3e7a31e8033caa42a134de2aa05d3144a8eceb0edd3af041f03d9",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-1195487518-script_types2]": "f68f1130cf830aa8e6632901d834e23693ec5ed111619c83eae12ef72f2a3609",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-3h-100h-4-255-script_types1]": "ac684c8ef0dd6f8456ccd70c955290720abe863fecb994a50c6f548111178f06",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-4-255-script_types0]": "2f95be5d0472b94ffe051d5753b9ca68f95b245633d8f76289f2768470f47319",
"TT_bitcoin-test_nonstandard_paths.py::test_signmessage[m-49-0-63-0-255-script_types4]": "73857c4de7ca4572bc7f9f428eb23be495569d938fabd35baf4e5bd04dcc31e3",
"TT_bitcoin-test_nonstandard_paths.py::test_signtx[m-1195487518-6-255-script_types3]": "0ffdf6683c3dace1725827bee5e0da3c489276bcc0f3cff411a4a848bb7a2ec8",
"TT_bitcoin-test_nonstandard_paths.py::test_signtx[m-1195487518-script_types2]": "c608ac3b16eb3b1a9e294a809b692c5633ba2c83681bf55c85b4c137bbde5810",
"TT_bitcoin-test_nonstandard_paths.py::test_signtx[m-3h-100h-4-255-script_types1]": "fa9fb399b0fd4f08e344e7581419e1b56d34995650a818f4e637afe8e3f9b3e8",
@ -2324,36 +2324,57 @@
"TT_bitcoin-test_peercoin.py::test_timestamp_included": "638313d3b73353020ea06a2c34c4b14ae87e864d7c027a882d6a55330030c6c0",
"TT_bitcoin-test_peercoin.py::test_timestamp_missing": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_bitcoin-test_peercoin.py::test_timestamp_missing_prevtx": "f524a9f7ee2fa91105477e0d673e3e5c5e1c1a13222d20d46ae2e375f9921c3d",
"TT_bitcoin-test_signmessage.py::test_signmessage[NFC message]": "c5651ab1894e8f21e848f828d8c3f762beaa2ad902bd3c9d13801b352bc08eab",
"TT_bitcoin-test_signmessage.py::test_signmessage[NFKD message]": "c5651ab1894e8f21e848f828d8c3f762beaa2ad902bd3c9d13801b352bc08eab",
"TT_bitcoin-test_signmessage.py::test_signmessage[bcash]": "cc8295b3150cb6b1c6335211b39d70dd8acad1eca15d489fc191649724cc9717",
"TT_bitcoin-test_signmessage.py::test_signmessage[decred-empty]": "f48a3472c03fd03e6f6e03d99018676eb25b41bf2b3e5540956a41c6c07e666d",
"TT_bitcoin-test_signmessage.py::test_signmessage[decred]": "ff44dcb2f60cd8f196ba178548c59e7f1691eaa71f9e41ca992b6e930d35ef2a",
"TT_bitcoin-test_signmessage.py::test_signmessage[grs-p2pkh]": "8b7f0f59eab5ce1d2d196d3484ee9fc33d62d9144fd54a0e8123a874bacef7cb",
"TT_bitcoin-test_signmessage.py::test_signmessage[grs-segwit-native]": "1f5557919e3b52e96ba55c053d73aa16ccd71327affce624527309ac0d5cb559",
"TT_bitcoin-test_signmessage.py::test_signmessage[grs-segwit-p2sh]": "d6c4b97ae276c207b1dc81ce3327c109d033e77cc804b8359a7b75a3f79600e2",
"TT_bitcoin-test_signmessage.py::test_signmessage[p2pkh long message]": "b6c4fe600b6eae57f19c6f9cb5915af28991f71e2d02f137c563a11b26c479d0",
"TT_bitcoin-test_signmessage.py::test_signmessage[p2pkh0]": "62b72798fafd22863766895d05366c69db5868a30ebec04abf0ad67cb432a45c",
"TT_bitcoin-test_signmessage.py::test_signmessage[p2pkh1]": "62b72798fafd22863766895d05366c69db5868a30ebec04abf0ad67cb432a45c",
"TT_bitcoin-test_signmessage.py::test_signmessage[p2pkh2]": "bdce33995b3558d9ec75c18011f05042e95e119840529ca3a6703baf675d1421",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-native long message]": "6d6520a2433ef20cbb81a98182511600e0be2d15994f430c0b88f9385e03ebd5",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-native0]": "d31fccdf4488e63c95a0b81e5a9f2a618015ead4916ab66aae17300ef357a177",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-native1]": "d31fccdf4488e63c95a0b81e5a9f2a618015ead4916ab66aae17300ef357a177",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-native2]": "e50e9207b1f724a0f3f78ec1900c5b3d65a3eec494f928ffc71b261b6b2861e0",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh long message]": "51d7ecb8fea5616c07afa145803e990e87c52ac284943a5bb6117a3445d71b57",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh0]": "c58074c8839166625c51365714f742085e2563c101314d67dc306cc69e7db5c7",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh1]": "c58074c8839166625c51365714f742085e2563c101314d67dc306cc69e7db5c7",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh2]": "0f538c0f4796b45217d0ed2cdcdad766a327d6f33ce98d3321e9f2b63b6b2a11",
"TT_bitcoin-test_signmessage.py::test_signmessage[t1 firmware path]": "ff0c289f5bfa0944958cff8508bd7ad34ca16d4edd1080a7d5bceccaf424529c",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[long_words]": "42c64bc197ebfa639ee48fe09b78e1d382b616e2b7ba151c7b5babf6fa9170a0",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[newlines]": "98f04abde4078abfcd36897e0fc66fd1a9a00ca188d6fa63a30c865abcc09237",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[no_spaces]": "1240d69f0f94f97c4bb434dd6196e21950b4d087d0cc0e98fd39b44309f280be",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[normal_text]": "45640b58fab8763acc9e246b6aed60e29baa0c73bd7a8250551f8476b30d9bae",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[single_line_over]": "9a403e897124ed6ccc2b21d660ce15ab182e4f4c1b6c0edcc0f58bd78d84c7dc",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_nospace]": "7a98ec40a4128fad97221ed557f7258140a33a45a4e880b6ca2852342db9e7ad",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_text]": "d46db3df7b17cb849e5f2d43f5550e9fc6d5905fe599f8b086630b576fcaa377",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination_trailing_newline": "b89e4fe57b92652962ca2348877a953b53a275cff2576af7044312d453e6fbcd",
"TT_bitcoin-test_signmessage.py::test_signmessage_path_warning": "ba5c8fe6b755708c8112a210b3897445c982356a34c948adbe576abc7021eba7",
"TT_bitcoin-test_signmessage.py::test_signmessage[NFC message]": "b92a01f39e829d21e16ede95550b2047ac9ea734a7c61f3e28faa16ebc036ccb",
"TT_bitcoin-test_signmessage.py::test_signmessage[NFKD message]": "b92a01f39e829d21e16ede95550b2047ac9ea734a7c61f3e28faa16ebc036ccb",
"TT_bitcoin-test_signmessage.py::test_signmessage[bcash]": "3c538fad2bd6a1fd6eb3c088d9571142e194e25c53b7f19abff1ef7e03040bb3",
"TT_bitcoin-test_signmessage.py::test_signmessage[decred-empty]": "bec877a114f2b28638caf4993e6ac8f83a19ec523b09a210dc0b817b1acf1a26",
"TT_bitcoin-test_signmessage.py::test_signmessage[decred]": "f5d7fddf8c0dfc802b58e565e826cde2d9dcf035c5d07539d16dc01e2c9732c6",
"TT_bitcoin-test_signmessage.py::test_signmessage[grs-p2pkh]": "d9e1788e58374fdd27b7fbfc014b8dee59948938dcfed47169a5b2acbe380e02",
"TT_bitcoin-test_signmessage.py::test_signmessage[grs-segwit-native]": "55f230ea818b01962d5f545f49e893776fa5d6c6b2bb95c78dec22b7e040b4ee",
"TT_bitcoin-test_signmessage.py::test_signmessage[grs-segwit-p2sh]": "103ebfb2f9506a61f3ee1f25de8345048318af26666c0cfd98b25898efe6125d",
"TT_bitcoin-test_signmessage.py::test_signmessage[p2pkh long message]": "fe7a417d23c473ad295ccdc52d93758bcb22527608f9eca92fb7b70ac36b9598",
"TT_bitcoin-test_signmessage.py::test_signmessage[p2pkh0]": "8004f64bdd53564afec8f5f290617fcfbd2a71274a84116b0837bc079601cdc1",
"TT_bitcoin-test_signmessage.py::test_signmessage[p2pkh1]": "8004f64bdd53564afec8f5f290617fcfbd2a71274a84116b0837bc079601cdc1",
"TT_bitcoin-test_signmessage.py::test_signmessage[p2pkh2]": "f38bed10be867b76b284c718033e7d6de592925bb0211e04afcd31247c334f3d",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-native long message]": "66c563dc08eb0e4d99669da02d7a7cb1264094c220c690dd222ba861828a6ae9",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-native0]": "6bc4d61dd9a8134b8c821c800e91cfcf15559a03e9b03e1e9144debb5fc720d1",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-native1]": "6bc4d61dd9a8134b8c821c800e91cfcf15559a03e9b03e1e9144debb5fc720d1",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-native2]": "30e5354089ce5519ed95646fffc9f3468587482a19b81163b719d253421e3645",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh long message]": "899791bd7a59f3bad9be65b6f7f833d8180a34ef83c867653f45c2b492a1d91f",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh0]": "cf9e2197fe85422b3db5110db75bca948cda95d40917ea0c5dc4cb442d0afb98",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh1]": "cf9e2197fe85422b3db5110db75bca948cda95d40917ea0c5dc4cb442d0afb98",
"TT_bitcoin-test_signmessage.py::test_signmessage[segwit-p2sh2]": "cb14f397c92ea679413d31b088e6ac149f3ac2406f28d5c07ac939531e1c3f7f",
"TT_bitcoin-test_signmessage.py::test_signmessage[t1 firmware path]": "0c706c1b116ead8623b6b667e57bed1bd2a43abd4b4eed510d025085a66a3e4c",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[NFC message]": "8696e425489452c226a59a6c6ef276f3faf80bfd4e1e1e868216b88f000f0260",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[NFKD message]": "8696e425489452c226a59a6c6ef276f3faf80bfd4e1e1e868216b88f000f0260",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[bcash]": "933d9466accabf431929e82499f29c29b37eb39b0cccd1b6a4a9b022ed6328ba",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[decred-empty]": "3961de777b7578dfd5e500285177284462b03c260f2a46f5827bbad906880b5a",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[decred]": "2b83146021fc6d4e870ecba9b79eeff057e51f1b92e8f6119afef4c7f1a090b4",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[grs-p2pkh]": "863ed334a92063c27233556e2ebe71c658d99d4a454ea2a7328d97200b4b65af",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[grs-segwit-native]": "b25d95a6546962059efc4b3f7749546a1b938c6084bd52a2a62322cfb4e522cf",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[grs-segwit-p2sh]": "382511a667f1cb2695c1fd140c3e1960f64d034c2cf94f39c017627bfc2d12ff",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[p2pkh long message]": "85a84af1b63221a1d0aa66e59a6323e67fcc25bc0f9599eeb4848f602720c3cb",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[p2pkh0]": "d45d875ec1ae14bb86f68673f5e5fd0597ff48cb3f225daeab7bd0ab069edc05",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[p2pkh1]": "d45d875ec1ae14bb86f68673f5e5fd0597ff48cb3f225daeab7bd0ab069edc05",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[p2pkh2]": "10a6cdf39c7d1c4f90cb7b741429c13cab6cb6fd0ec082a82f22220bab185756",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[segwit-native long message]": "ba43a9c316206f12559022c1a6170842b5abc1e4b9b31c41cd183ef71670f785",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[segwit-native0]": "8a50b6cc3eb28bbb186c4e113201425392ac8ebb1bb8f03e817b96b8246a9bd3",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[segwit-native1]": "8a50b6cc3eb28bbb186c4e113201425392ac8ebb1bb8f03e817b96b8246a9bd3",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[segwit-native2]": "ec4a77e34885849a9302779fc47e260c4d943a2ed4f8e6f962769a538261ebd3",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[segwit-p2sh long message]": "6fa6739fafc24cde1d9c820bb5dc6abd94a11283fbf40b5967a29c34bb60149e",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[segwit-p2sh0]": "9221745002c1e2d346d9822e358a13081db57c6a4a459eafbe6e83ee3a037d23",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[segwit-p2sh1]": "9221745002c1e2d346d9822e358a13081db57c6a4a459eafbe6e83ee3a037d23",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[segwit-p2sh2]": "d9d3cd25802f3d429d665f1c987d4f895bdd03ab86f13820282b4667991b9285",
"TT_bitcoin-test_signmessage.py::test_signmessage_info[t1 firmware path]": "236dba354336b318a77a8de3ef74abf6fc703b6e044630884b581d72ea6d0963",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[long_words]": "da3be9ddcab84e53a1be8e6655c22ec074b2877e3934a2ff686ce11f7c26ffe9",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[newlines]": "c2c597b4c10949b2b28aad71c72cef1919303d4dd9bea75e8951604bb4517322",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[no_spaces]": "2be7fd38861a754f14ad0893a29e37d0ba351053c452442d31dae801a691bfbf",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[normal_text]": "3a72fcb8928e7fc80566564c98057dea63fdd4c3abf04667ea53f78457b56ecf",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[single_line_over]": "29bdaa48afbc6e69e20b6f8cba55dbd0d551a0c5cf2f0b758b684af7d8f703c2",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_nospace]": "1d43873bc11a567ccd03f9e6e4ab42c930641a5ee73922d4dd9ed597953a854a",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_text]": "31b267c4299f3eeea2d0fcb9800cfcf2d97ded9660b1a1d373ff1fc75da1bfcd",
"TT_bitcoin-test_signmessage.py::test_signmessage_pagination_trailing_newline": "0da2f2b6bd625bc5c8f9982ebd83f604748059a77bc1a49e857a07fd24968a0f",
"TT_bitcoin-test_signmessage.py::test_signmessage_path_warning": "705b683563a06d8eaad242a794e5c8683d41d560a9642761d183e79d85510bd7",
"TT_bitcoin-test_signtx.py::test_attack_change_input_address": "406e9f0bf3be42d1f41176b0d1f97b7286e834e1d15b5397904f981cea9fc5e0",
"TT_bitcoin-test_signtx.py::test_attack_change_outputs": "24ac4be4d6bcb7cdfd372bb3441f10563e13fd684ed3fdcc79c0c8e97830326b",
"TT_bitcoin-test_signtx.py::test_attack_modify_change_address": "477e69874284b2a1ee6e508983eb784fe7742574cc05c7987f45784e2e5d871e",
@ -2499,21 +2520,21 @@
"TT_bitcoin-test_signtx_taproot.py::test_send_p2tr[False]": "6abb97c5b7d3488b7d30018bf970507ada2f597b6b9b62ee0d9beb5d422e254c",
"TT_bitcoin-test_signtx_taproot.py::test_send_p2tr[True]": "2d6f85827d80251c7759b5ab75ca65640d415d40877ea5d64a677190b8715f69",
"TT_bitcoin-test_signtx_taproot.py::test_send_two_with_change": "fb46ca21976ae67dfbe73f5057ff0304bda4f4000c341fcc8bf856d23c2d177f",
"TT_bitcoin-test_verifymessage.py::test_message_grs": "e10ff287f3399371f2ae44b044a38143e7ea567f72733d12004098b44403078d",
"TT_bitcoin-test_verifymessage.py::test_message_long": "b0541c5c1d156381335f6b164308f513d844f44cebb00833a3802d8b9778d046",
"TT_bitcoin-test_verifymessage.py::test_message_testnet": "3b2ee73c971522921685968e59fb3633c27f1270cb2fb1291d7dbcc49358791a",
"TT_bitcoin-test_verifymessage.py::test_message_verify": "7a0edeeffa652124f4fc9168a053adedbf92fb56b58dcca0c3f236e0b98bc9cd",
"TT_bitcoin-test_verifymessage.py::test_message_verify_bcash": "af1ec707699d27959dae384975402d7af5c6f5b371a06fc545bf3a16955366cb",
"TT_bitcoin-test_verifymessage.py::test_verify_bitcoind": "9e5f39b515aea597f55fee4d26bbab9024fda32b535144f5023cd4172cacc03c",
"TT_bitcoin-test_verifymessage.py::test_verify_utf": "9bbb6c7e59c38f3ea4ef07ca5345506ab423f078ceed2d9fed5a46cb8ca33637",
"TT_bitcoin-test_verifymessage_segwit.py::test_message_long": "83f30975bf2721326f1896f7442739cb21728a6b93467351b668aca44610fc27",
"TT_bitcoin-test_verifymessage_segwit.py::test_message_testnet": "d1c3ce3dc5f2655c10e1e82bb595ead730c8b50c729cf9042576a9e0cb144b22",
"TT_bitcoin-test_verifymessage_segwit.py::test_message_verify": "0bb1466169587736d9258683fc0f3e58bcc6caf298de29765f7ecbe5208977d8",
"TT_bitcoin-test_verifymessage_segwit.py::test_verify_utf": "5416118c11b492d021ce08e71d9082b27f2f0cf1cd65da4cd7a20ae4eecd3f0a",
"TT_bitcoin-test_verifymessage_segwit_native.py::test_message_long": "888740b8ff7d52fe9ec18268c3dde48010228db60be4c8dcc2c0bb1005ffcae8",
"TT_bitcoin-test_verifymessage_segwit_native.py::test_message_testnet": "4a5e2ee5f42a9bee7656041ed46f0287e5cfd49177b052f1e2a8ae8f71b7d867",
"TT_bitcoin-test_verifymessage_segwit_native.py::test_message_verify": "f9acd7688d2c08c7f596aad2dcf08301daeec1042fbe3284ec6aade9428c82fb",
"TT_bitcoin-test_verifymessage_segwit_native.py::test_verify_utf": "c2ef38b50b65ae726f258fa24f3d87a6abd736a7bdec9ba77c54266ef26b402d",
"TT_bitcoin-test_verifymessage.py::test_message_grs": "0117f15331639fd915916dc9fc33df1e5fb6ff419d7835c4fbfa63f0f448d5c6",
"TT_bitcoin-test_verifymessage.py::test_message_long": "5be82d795fc8de51d3b23fbbe0f6ca4a31f745325f1668ff0a209a9af9d89dd2",
"TT_bitcoin-test_verifymessage.py::test_message_testnet": "888422306be9265dbff77da9f74faef242c77304f3dc29b874a7e382497f7799",
"TT_bitcoin-test_verifymessage.py::test_message_verify": "0482e74cc56113072a40fe0fc9c77266f824e5bbd40f5e0456ea2e8c05045c89",
"TT_bitcoin-test_verifymessage.py::test_message_verify_bcash": "cf22932a05a0db1f4113bfa793d507009d90a48a8deda2b057b35a8bab2e56c3",
"TT_bitcoin-test_verifymessage.py::test_verify_bitcoind": "3e2a3c1a7b7be9a3cce9cf94d10361bc12bef0c63b1ff8e9d08202d8e876dceb",
"TT_bitcoin-test_verifymessage.py::test_verify_utf": "ae1867d920f8e18e277e03794d0566bcf1255f55ecbd8ef02bd7cbf8f14e1239",
"TT_bitcoin-test_verifymessage_segwit.py::test_message_long": "7da343c43d8d86bb17ba376d70b6002f455d44495d1cb62d322ec8137bdcda0d",
"TT_bitcoin-test_verifymessage_segwit.py::test_message_testnet": "b1f9f1864b9f327518c1ba3a1770072bea7d40c5bde442202206e2fce52171e2",
"TT_bitcoin-test_verifymessage_segwit.py::test_message_verify": "e600dd4ab19d4c55169cfbe73998fd3294a1fab45a1323289478b6a17b7f152c",
"TT_bitcoin-test_verifymessage_segwit.py::test_verify_utf": "ad1e3b8a0d1738020f002bb24824b529fa8ccdcf52cfcea354fbfc9c88b9961f",
"TT_bitcoin-test_verifymessage_segwit_native.py::test_message_long": "70e847910f378cc029d1afdfe87d4a03add5ecba99d57cf2377e8a377d578d86",
"TT_bitcoin-test_verifymessage_segwit_native.py::test_message_testnet": "93bf717a8b4d4371af323d07f0f4538539a5199f8c811d402445a4f08789abef",
"TT_bitcoin-test_verifymessage_segwit_native.py::test_message_verify": "ead03a1ab9def68c0c41471fc02f346d6dee943c9479bfe24d88a22e897bee63",
"TT_bitcoin-test_verifymessage_segwit_native.py::test_verify_utf": "0a7562efc888c57ced1fbcdbea8255bf604ef167098969b313e9a5531203670a",
"TT_bitcoin-test_zcash.py::test_external_presigned": "58ca129cf30e1cfb9a4b393967b859094cf7b7a3095bb1962f9199b52fac8245",
"TT_bitcoin-test_zcash.py::test_one_one_fee_sapling": "5b0b0f76aa1fb8eace9848f3dc9fe6e3e4730a85de184192fec9dce364bbec36",
"TT_bitcoin-test_zcash.py::test_spend_old_versions": "921df31d90290b36c1c650451c4979a85637bbe3e2e918d09d826e63db9eb597",
@ -2882,13 +2903,13 @@
"TT_ethereum-test_definitions.py::test_external_token": "179f43de25b6a293ff255b4f9e1d09d78df1a928319d9b5789931b7bb7371a61",
"TT_ethereum-test_definitions.py::test_method_builtin[_call_getaddress]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_ethereum-test_definitions.py::test_method_builtin[_call_sign_typed_data]": "13438d0a9bb21b8d891792bdd119265ec2956c046ecb047be746c20a45872b8a",
"TT_ethereum-test_definitions.py::test_method_builtin[_call_signmessage]": "9f9f78467605a33d51a717609b4597cb700e984fa4fabf0155377195d4a89032",
"TT_ethereum-test_definitions.py::test_method_builtin[_call_signmessage]": "cfd045d3ffa9ea1d1622ff50c546cda1f7678e25540c02b23ac3dae4d1a0dbc3",
"TT_ethereum-test_definitions.py::test_method_def_missing[_call_getaddress]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_ethereum-test_definitions.py::test_method_def_missing[_call_sign_typed_data]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_ethereum-test_definitions.py::test_method_def_missing[_call_signmessage]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_ethereum-test_definitions.py::test_method_external[_call_getaddress]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_ethereum-test_definitions.py::test_method_external[_call_sign_typed_data]": "3f0c9e28779aa87144907f416b2871a19988c36592594b8592c99a989096393e",
"TT_ethereum-test_definitions.py::test_method_external[_call_signmessage]": "434e46713b1630154b7920be087ebd5461694d45dc9ccb1a86575e233721b9b0",
"TT_ethereum-test_definitions.py::test_method_external[_call_signmessage]": "433d26ebebf355ffc86eac6d8146447790b1f4d8bd34121b3a631a8dbc30e74b",
"TT_ethereum-test_definitions.py::test_method_external_mismatch[_call_getaddress]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_ethereum-test_definitions.py::test_method_external_mismatch[_call_sign_typed_data]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_ethereum-test_definitions.py::test_method_external_mismatch[_call_signmessage]": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
@ -2937,24 +2958,24 @@
"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[structs_arrays_v4]": "2b0c138165ce995f2004113a957b1e85126ae4137ac91b91c33e9fabd5e937a7",
"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data_cancel": "946b7e16c07550e996a7b550f4936c93e0f305539e44c6d0a1f8d6e2b8a54ce9",
"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data_show_more_button": "ca335555219c02ab3bf829c018e893ed3227792043d996459aa9d6a96b0c9d61",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters0-result0]": "06e9d414b00abe569196dad205a41f9c1bccdcb77892e692716e2126d8bfa569",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters1-result1]": "4456700d8527570c7b73cf46fc69b3c8abe0370cecca027696ecef1f28ddbed6",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters2-result2]": "77c3f915485221d6ab2ea89eaf18e4c9db754d66a69a203f6913bb471c285e57",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters3-result3]": "7c04f107a9dff9d16e47329eb296a248b2952548130f549954961b662f29131c",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters4-result4]": "6e00dd019f98a528de814065ca679db2a4ee54a5358ea765702d281293c626d4",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters5-result5]": "62550d4feeb47f1039b47030b2bd88ddaf5b8bbee666c8e244f1ffad29e75049",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters6-result6]": "9d945f83dde0855a84f782ef21342070d4ac2c6042588cea9c47639b94f25bfe",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters7-result7]": "50bacf21290a352fd0c22ced3f09e887e6a00c4501f8e5e4bfcfa3a150fec615",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters8-result8]": "978cb33b260cfb11a4eff1ad9fa515e8179aec72e508ad89e3436b6c58658292",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters0-result0]": "722cac3140294153823df53852bcfb0a57906e5d4013baa9139eef0c09ef24a5",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters1-result1]": "9b9b0b623491620cb24df84fe0e3ca5c0963d837509760dfaadb951cd746f678",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters2-result2]": "cb703c8a7d3e32801a03b8b5e40f1ede5a002a92dd76faf07532a2f441e01aae",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters3-result3]": "d2ab773f54dc8b3819ddb9e8cd708d1118393faf4a7a1833161f94dc902c701a",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters4-result4]": "0f79f10e8152b78f8bb813471675b576bc743784e8a44055e7ebd7844fcf1ff9",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters5-result5]": "ae81e1ff1f5776422944187a422142fcbb83f07a5e3bef42c6db752cf6a2c5d5",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters6-result6]": "171614ecbeae478d995a7402b6853b33d8970e8fbe1570c630003a568c0846a7",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters7-result7]": "0849ed619428ada8a94b47a66d160436047e0503b5f82ee874976c54590a462d",
"TT_ethereum-test_sign_verify_message.py::test_verify_invalid": "722cac3140294153823df53852bcfb0a57906e5d4013baa9139eef0c09ef24a5",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters0-result0]": "80c45e65c861c1668f272398c4a790cc9dd0613aace21bfe554c9a685e2eae8f",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters1-result1]": "3be516e8e20d4c2e7f8c5f9ef4039eddb60ee43700a97087674d5af5604f6229",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters2-result2]": "dba56b7e5def913c477a5a4cd56976f17316a53856a1c4e6a5981d8d7972464b",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters3-result3]": "3e4a965130a869c772ce2334b2fd1a789efc382dee4527f7eb4244af39de1a72",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters4-result4]": "b55f2aa360c610e470b1af6becff9a69e49d56476b51dcc61de43cf4a24f599f",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters5-result5]": "6c710f6210556bf2ded8a6027776280ec23b8724eebd99cb4332552d260a4c59",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters6-result6]": "2d8d1acf5e6a4010cdb9feb342e10f627fd64586e49ad8ea57d422a3fc148ce3",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters7-result7]": "5db2cdd9461ef667c339619a42fce89a7e46c7ae576d83712efebbae8cd4ed09",
"TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters8-result8]": "985b867aeda08c981c8c610e94f454c8529fc4d14c9cb01881499784c5a4b6c1",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters0-result0]": "cbea228b1a6582289d57b5ef0017e9b52dbaf1817078039590c9beebe5ba6344",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters1-result1]": "77d7983e6a7bd6450e1d65f0f3552c34ec81ac39be60aa8d17186069e87ddc98",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters2-result2]": "f612aed993f77906c8990d645a9bd4abfb30d57989121ba2e10cfd157a811983",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters3-result3]": "5c9607cef8d99d24c5a3b1554369a15391bc58ca90a815cb37689c8f05f48dc6",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters4-result4]": "46148fc0e4ddad92ddf4986b72f557c4316ff6a5d386b12a284a90d0bee46820",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters5-result5]": "b7e5ac80950f2afcd1db8dca4d37236ab434e810c4e5b4b69f97bb073f14d505",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters6-result6]": "c175ff9348c8bfbdffed2809f7b8f158ed1e7896abc19b6191245ceca01d594f",
"TT_ethereum-test_sign_verify_message.py::test_verify[parameters7-result7]": "69f815f79ed5dfd60f009bbe3024d7e910fe37ee32377c955ee29b569fd4f58d",
"TT_ethereum-test_sign_verify_message.py::test_verify_invalid": "cbea228b1a6582289d57b5ef0017e9b52dbaf1817078039590c9beebe5ba6344",
"TT_ethereum-test_signtx.py::test_data_streaming": "9a89cb6f1a61c69a35a7c5f53239d5ffce3ff7bc07a2a08f67266ebd753de3f7",
"TT_ethereum-test_signtx.py::test_sanity_checks": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
"TT_ethereum-test_signtx.py::test_sanity_checks_eip1559": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
@ -3236,7 +3257,7 @@
"TT_test_cancel.py::test_cancel_message_via_cancel[message1]": "1bd3157d54327e33542f89dcac6c7cd23808f7c9aa1b0adb390e5fcc1fd858a5",
"TT_test_cancel.py::test_cancel_message_via_initialize[message0]": "1bd3157d54327e33542f89dcac6c7cd23808f7c9aa1b0adb390e5fcc1fd858a5",
"TT_test_cancel.py::test_cancel_message_via_initialize[message1]": "1bd3157d54327e33542f89dcac6c7cd23808f7c9aa1b0adb390e5fcc1fd858a5",
"TT_test_cancel.py::test_cancel_on_paginated": "a6aadac2d8820228eb8fc0152141350f176095aeb2d9fd6e41581f75a8b962b7",
"TT_test_cancel.py::test_cancel_on_paginated": "498ffee2ea02e2783466cbb993f0cd83eedd3b67afde37b5d1f713fc996c1455",
"TT_test_debuglink.py::test_softlock_instability": "55cb4cbeec68bd8ccee460034677cf8053f8f688d5c3559f360c38a205b34e37",
"TT_test_firmware_hash.py::test_firmware_hash_emu": "2a63f0bd10ba99e223f571482d4af635653bb8a3bddc1d8400777ee5519bc605",
"TT_test_firmware_hash.py::test_firmware_hash_hw": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
@ -3298,10 +3319,10 @@
"TT_test_protection_levels.py::test_passphrase_reporting[False]": "6b2b5aa5a41031a8eeb980d0f53dfdf31c045b8b22c51fbc9d361b2b4fe132cd",
"TT_test_protection_levels.py::test_passphrase_reporting[True]": "adc28ee6969d9c6644e7769598ee761ee4a6f8bf8bca2453875042018d8af4cb",
"TT_test_protection_levels.py::test_ping": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739",
"TT_test_protection_levels.py::test_sign_message": "faceae412067c778b09810feb7746bbf6decbe83de8fde215287b1af243675c6",
"TT_test_protection_levels.py::test_sign_message": "9bac92f0f3d6e160a8ebebe972b8cfa69bcb39ec4c8df57967cdbcf22cd4b37d",
"TT_test_protection_levels.py::test_signtx": "66d6126817dfb2df7a08b2deef7dd18a07763400f4d88c4776571cd7a8fc4554",
"TT_test_protection_levels.py::test_unlocked": "4488e2b6f06fdff05749ac271d080182f1c95645de37898457ff12f0fb190381",
"TT_test_protection_levels.py::test_verify_message_t2": "c9aa3fa6229cc9573d471e513565bf169ce465c8f8e8092f6c6effe3fcbce5d6",
"TT_test_protection_levels.py::test_verify_message_t2": "cc09f0acf9e48b1355dae0be65a2a97abbe2811808feee08d46ae7146ce6bb6f",
"TT_test_protection_levels.py::test_wipe_device": "7ff017de646b7cf70832605e1750c635d0eb661d51534b56007b49e82b927011",
"TT_test_sdcard.py::test_sd_format": "83d0d9b4eab3bf0eafc22d7d95e8b70bce477ba9c8b4ba13eeca9380ad5fdafa",
"TT_test_sdcard.py::test_sd_no_format": "14511e3d3ee535d97287d8ade25101e8c16db17c1dc5d3151b91e5e8eba61ba5",