mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-26 08:29:26 +00:00
feat(core): send address & public key response before showing StatusScreen
Co-authored-by: matejcik <ja@matejcik.cz>
This commit is contained in:
parent
3f520b4ce2
commit
946fc89449
1
core/.changelog.d/3666.fixed
Normal file
1
core/.changelog.d/3666.fixed
Normal file
@ -0,0 +1 @@
|
|||||||
|
[T3T1] Show confirmation layout after sending response to host.
|
@ -709,7 +709,6 @@ static void _librust_qstrs(void) {
|
|||||||
MP_QSTR_time_ms;
|
MP_QSTR_time_ms;
|
||||||
MP_QSTR_timer;
|
MP_QSTR_timer;
|
||||||
MP_QSTR_title;
|
MP_QSTR_title;
|
||||||
MP_QSTR_title_success;
|
|
||||||
MP_QSTR_total_fee_new;
|
MP_QSTR_total_fee_new;
|
||||||
MP_QSTR_total_len;
|
MP_QSTR_total_len;
|
||||||
MP_QSTR_touch_event;
|
MP_QSTR_touch_event;
|
||||||
|
@ -543,7 +543,6 @@ extern "C" fn new_flow_get_address(n_args: usize, args: *const Obj, kwargs: *mut
|
|||||||
let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
|
let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
|
||||||
let path: Option<TString> = kwargs.get(Qstr::MP_QSTR_path)?.try_into_option()?;
|
let path: Option<TString> = kwargs.get(Qstr::MP_QSTR_path)?.try_into_option()?;
|
||||||
let xpubs: Obj = kwargs.get(Qstr::MP_QSTR_xpubs)?;
|
let xpubs: Obj = kwargs.get(Qstr::MP_QSTR_xpubs)?;
|
||||||
let title_success: TString = kwargs.get(Qstr::MP_QSTR_title_success)?.try_into()?;
|
|
||||||
let br_code: u16 = kwargs.get(Qstr::MP_QSTR_br_code)?.try_into()?;
|
let br_code: u16 = kwargs.get(Qstr::MP_QSTR_br_code)?.try_into()?;
|
||||||
let br_name: TString = kwargs.get(Qstr::MP_QSTR_br_name)?.try_into()?;
|
let br_name: TString = kwargs.get(Qstr::MP_QSTR_br_name)?.try_into()?;
|
||||||
|
|
||||||
@ -558,7 +557,6 @@ extern "C" fn new_flow_get_address(n_args: usize, args: *const Obj, kwargs: *mut
|
|||||||
account,
|
account,
|
||||||
path,
|
path,
|
||||||
xpubs,
|
xpubs,
|
||||||
title_success,
|
|
||||||
br_code,
|
br_code,
|
||||||
br_name,
|
br_name,
|
||||||
)?;
|
)?;
|
||||||
@ -1414,7 +1412,6 @@ pub static mp_module_trezorui_api: Module = obj_module! {
|
|||||||
/// account: str | None,
|
/// account: str | None,
|
||||||
/// path: str | None,
|
/// path: str | None,
|
||||||
/// xpubs: list[tuple[str, str]],
|
/// xpubs: list[tuple[str, str]],
|
||||||
/// title_success: str,
|
|
||||||
/// br_code: ButtonRequestType,
|
/// br_code: ButtonRequestType,
|
||||||
/// br_name: str,
|
/// br_name: str,
|
||||||
/// ) -> LayoutObj[UiResult]:
|
/// ) -> LayoutObj[UiResult]:
|
||||||
|
@ -602,7 +602,6 @@ impl FirmwareUI for UIBolt {
|
|||||||
_account: Option<TString<'static>>,
|
_account: Option<TString<'static>>,
|
||||||
_path: Option<TString<'static>>,
|
_path: Option<TString<'static>>,
|
||||||
_xpubs: Obj,
|
_xpubs: Obj,
|
||||||
_title_success: TString<'static>,
|
|
||||||
_br_code: u16,
|
_br_code: u16,
|
||||||
_br_name: TString<'static>,
|
_br_name: TString<'static>,
|
||||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
|
@ -736,7 +736,6 @@ impl FirmwareUI for UICaesar {
|
|||||||
_account: Option<TString<'static>>,
|
_account: Option<TString<'static>>,
|
||||||
_path: Option<TString<'static>>,
|
_path: Option<TString<'static>>,
|
||||||
_xpubs: Obj,
|
_xpubs: Obj,
|
||||||
_title_success: TString<'static>,
|
|
||||||
_br_code: u16,
|
_br_code: u16,
|
||||||
_br_name: TString<'static>,
|
_br_name: TString<'static>,
|
||||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
|
@ -172,12 +172,12 @@ impl StatusScreen {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_success_timeout(msg: TString<'static>) -> Self {
|
pub fn new_success_timeout(msg: TString<'static>, time_ms: u32) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
theme::ICON_SIMPLE_CHECKMARK30,
|
theme::ICON_SIMPLE_CHECKMARK30,
|
||||||
theme::GREEN_LIME,
|
theme::GREEN_LIME,
|
||||||
theme::GREEN_LIGHT,
|
theme::GREEN_LIGHT,
|
||||||
DismissType::Timeout(Timeout::new(TIMEOUT_MS)),
|
DismissType::Timeout(Timeout::new(time_ms)),
|
||||||
msg,
|
msg,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
component::{AddressDetails, Frame, PromptScreen, StatusScreen, SwipeContent, VerticalMenu},
|
component::{AddressDetails, Frame, PromptScreen, SwipeContent, VerticalMenu},
|
||||||
theme,
|
theme,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,7 +30,6 @@ const QR_BORDER: i16 = 4;
|
|||||||
pub enum GetAddress {
|
pub enum GetAddress {
|
||||||
Address,
|
Address,
|
||||||
Tap,
|
Tap,
|
||||||
Confirmed,
|
|
||||||
Menu,
|
Menu,
|
||||||
QrCode,
|
QrCode,
|
||||||
AccountInfo,
|
AccountInfo,
|
||||||
@ -64,9 +63,8 @@ impl FlowController for GetAddress {
|
|||||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||||
match (self, msg) {
|
match (self, msg) {
|
||||||
(Self::Address, FlowMsg::Info) => Self::Menu.goto(),
|
(Self::Address, FlowMsg::Info) => Self::Menu.goto(),
|
||||||
(Self::Tap, FlowMsg::Confirmed) => Self::Confirmed.swipe_up(),
|
(Self::Tap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||||
(Self::Tap, FlowMsg::Info) => Self::Menu.swipe_left(),
|
(Self::Tap, FlowMsg::Info) => Self::Menu.swipe_left(),
|
||||||
(Self::Confirmed, _) => self.return_msg(FlowMsg::Confirmed),
|
|
||||||
(Self::Menu, FlowMsg::Choice(0)) => Self::QrCode.swipe_left(),
|
(Self::Menu, FlowMsg::Choice(0)) => Self::QrCode.swipe_left(),
|
||||||
(Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(),
|
(Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(),
|
||||||
(Self::Menu, FlowMsg::Choice(2)) => Self::Cancel.swipe_left(),
|
(Self::Menu, FlowMsg::Choice(2)) => Self::Cancel.swipe_left(),
|
||||||
@ -93,7 +91,6 @@ pub fn new_get_address(
|
|||||||
account: Option<TString<'static>>,
|
account: Option<TString<'static>>,
|
||||||
path: Option<TString<'static>>,
|
path: Option<TString<'static>>,
|
||||||
xpubs: Obj, // TODO: get rid of Obj
|
xpubs: Obj, // TODO: get rid of Obj
|
||||||
title_success: TString<'static>,
|
|
||||||
br_code: u16,
|
br_code: u16,
|
||||||
br_name: TString<'static>,
|
br_name: TString<'static>,
|
||||||
) -> Result<SwipeFlow, error::Error> {
|
) -> Result<SwipeFlow, error::Error> {
|
||||||
@ -131,14 +128,6 @@ pub fn new_get_address(
|
|||||||
.with_swipe(Direction::Left, SwipeSettings::default())
|
.with_swipe(Direction::Left, SwipeSettings::default())
|
||||||
.map(super::util::map_to_confirm);
|
.map(super::util::map_to_confirm);
|
||||||
|
|
||||||
let content_confirmed = Frame::left_aligned(
|
|
||||||
TR::words__title_success.into(),
|
|
||||||
StatusScreen::new_success_timeout(title_success),
|
|
||||||
)
|
|
||||||
.with_footer(TR::instructions__continue_in_app.into(), None)
|
|
||||||
.with_result_icon(theme::ICON_BULLET_CHECKMARK, theme::GREEN_LIGHT)
|
|
||||||
.map(|_| Some(FlowMsg::Confirmed));
|
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
let content_menu = Frame::left_aligned(
|
let content_menu = Frame::left_aligned(
|
||||||
"".into(),
|
"".into(),
|
||||||
@ -200,7 +189,6 @@ pub fn new_get_address(
|
|||||||
let mut res = SwipeFlow::new(&GetAddress::Address)?;
|
let mut res = SwipeFlow::new(&GetAddress::Address)?;
|
||||||
res.add_page(&GetAddress::Address, content_address)?
|
res.add_page(&GetAddress::Address, content_address)?
|
||||||
.add_page(&GetAddress::Tap, content_tap)?
|
.add_page(&GetAddress::Tap, content_tap)?
|
||||||
.add_page(&GetAddress::Confirmed, content_confirmed)?
|
|
||||||
.add_page(&GetAddress::Menu, content_menu)?
|
.add_page(&GetAddress::Menu, content_menu)?
|
||||||
.add_page(&GetAddress::QrCode, content_qr)?
|
.add_page(&GetAddress::QrCode, content_qr)?
|
||||||
.add_page(&GetAddress::AccountInfo, content_account)?
|
.add_page(&GetAddress::AccountInfo, content_account)?
|
||||||
|
@ -9,6 +9,7 @@ use crate::{
|
|||||||
ui::{
|
ui::{
|
||||||
component::{
|
component::{
|
||||||
connect::Connect,
|
connect::Connect,
|
||||||
|
swipe_detect::SwipeSettings,
|
||||||
text::{
|
text::{
|
||||||
op::OpTextLayout,
|
op::OpTextLayout,
|
||||||
paragraphs::{
|
paragraphs::{
|
||||||
@ -19,7 +20,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
Border, CachedJpeg, ComponentExt, Empty, FormattedText, Never, Timeout,
|
Border, CachedJpeg, ComponentExt, Empty, FormattedText, Never, Timeout,
|
||||||
},
|
},
|
||||||
geometry::{self, Offset},
|
geometry::{self, Direction, Offset},
|
||||||
layout::{
|
layout::{
|
||||||
obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
||||||
util::{PropsList, RecoveryType},
|
util::{PropsList, RecoveryType},
|
||||||
@ -630,7 +631,6 @@ impl FirmwareUI for UIDelizia {
|
|||||||
account: Option<TString<'static>>,
|
account: Option<TString<'static>>,
|
||||||
path: Option<TString<'static>>,
|
path: Option<TString<'static>>,
|
||||||
xpubs: Obj,
|
xpubs: Obj,
|
||||||
title_success: TString<'static>,
|
|
||||||
br_code: u16,
|
br_code: u16,
|
||||||
br_name: TString<'static>,
|
br_name: TString<'static>,
|
||||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
@ -645,7 +645,6 @@ impl FirmwareUI for UIDelizia {
|
|||||||
account,
|
account,
|
||||||
path,
|
path,
|
||||||
xpubs,
|
xpubs,
|
||||||
title_success,
|
|
||||||
br_code,
|
br_code,
|
||||||
br_name,
|
br_name,
|
||||||
)?;
|
)?;
|
||||||
@ -1045,24 +1044,34 @@ impl FirmwareUI for UIDelizia {
|
|||||||
|
|
||||||
fn show_success(
|
fn show_success(
|
||||||
title: TString<'static>,
|
title: TString<'static>,
|
||||||
_button: TString<'static>,
|
button: TString<'static>,
|
||||||
description: TString<'static>,
|
description: TString<'static>,
|
||||||
_allow_cancel: bool,
|
_allow_cancel: bool,
|
||||||
_time_ms: u32,
|
time_ms: u32,
|
||||||
) -> Result<Gc<LayoutObj>, Error> {
|
) -> Result<Gc<LayoutObj>, Error> {
|
||||||
|
let instruction = if button.is_empty() {
|
||||||
|
TR::instructions__tap_to_continue.into()
|
||||||
|
} else {
|
||||||
|
button
|
||||||
|
};
|
||||||
// description used in the Footer
|
// description used in the Footer
|
||||||
let description = if description.is_empty() {
|
let description = if description.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(description)
|
Some(description)
|
||||||
};
|
};
|
||||||
let content = StatusScreen::new_success(title);
|
let content = if time_ms > 0 {
|
||||||
|
StatusScreen::new_success_timeout(title, time_ms)
|
||||||
|
} else {
|
||||||
|
StatusScreen::new_success(title)
|
||||||
|
};
|
||||||
let layout = LayoutObj::new(SwipeUpScreen::new(
|
let layout = LayoutObj::new(SwipeUpScreen::new(
|
||||||
Frame::left_aligned(
|
Frame::left_aligned(
|
||||||
TR::words__title_success.into(),
|
TR::words__title_success.into(),
|
||||||
SwipeContent::new(content).with_no_attach_anim(),
|
SwipeContent::new(content).with_no_attach_anim(),
|
||||||
)
|
)
|
||||||
.with_swipeup_footer(description)
|
.with_footer(instruction, description)
|
||||||
|
.with_swipe(Direction::Up, SwipeSettings::default())
|
||||||
.with_result_icon(theme::ICON_BULLET_CHECKMARK, theme::GREEN_LIGHT),
|
.with_result_icon(theme::ICON_BULLET_CHECKMARK, theme::GREEN_LIGHT),
|
||||||
))?;
|
))?;
|
||||||
Ok(layout)
|
Ok(layout)
|
||||||
|
@ -203,7 +203,6 @@ pub trait FirmwareUI {
|
|||||||
account: Option<TString<'static>>,
|
account: Option<TString<'static>>,
|
||||||
path: Option<TString<'static>>,
|
path: Option<TString<'static>>,
|
||||||
xpubs: Obj, // TODO: replace Obj
|
xpubs: Obj, // TODO: replace Obj
|
||||||
title_success: TString<'static>,
|
|
||||||
br_code: u16,
|
br_code: u16,
|
||||||
br_name: TString<'static>,
|
br_name: TString<'static>,
|
||||||
) -> Result<impl LayoutMaybeTrace, Error>;
|
) -> Result<impl LayoutMaybeTrace, Error>;
|
||||||
|
@ -362,7 +362,6 @@ def flow_get_address(
|
|||||||
account: str | None,
|
account: str | None,
|
||||||
path: str | None,
|
path: str | None,
|
||||||
xpubs: list[tuple[str, str]],
|
xpubs: list[tuple[str, str]],
|
||||||
title_success: str,
|
|
||||||
br_code: ButtonRequestType,
|
br_code: ButtonRequestType,
|
||||||
br_name: str,
|
br_name: str,
|
||||||
) -> LayoutObj[UiResult]:
|
) -> LayoutObj[UiResult]:
|
||||||
|
@ -9,6 +9,7 @@ from .keychain import with_keychain
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import Address, GetAddress, HDNodeType
|
from trezor.messages import Address, GetAddress, HDNodeType
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.coininfo import CoinInfo
|
from apps.common.coininfo import CoinInfo
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
@ -35,14 +36,19 @@ def _get_xpubs(
|
|||||||
|
|
||||||
|
|
||||||
@with_keychain
|
@with_keychain
|
||||||
async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Address:
|
async def get_address(
|
||||||
|
msg: GetAddress, keychain: Keychain, coin: CoinInfo
|
||||||
|
) -> MaybeEarlyResponse[Address]:
|
||||||
|
from trezor import TR
|
||||||
from trezor.enums import InputScriptType
|
from trezor.enums import InputScriptType
|
||||||
from trezor.messages import Address
|
from trezor.messages import Address
|
||||||
from trezor.ui.layouts import (
|
from trezor.ui.layouts import (
|
||||||
confirm_multisig_different_paths_warning,
|
confirm_multisig_different_paths_warning,
|
||||||
confirm_multisig_warning,
|
confirm_multisig_warning,
|
||||||
show_address,
|
show_address,
|
||||||
|
show_continue_in_app,
|
||||||
)
|
)
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common.address_mac import get_address_mac
|
from apps.common.address_mac import get_address_mac
|
||||||
from apps.common.paths import address_n_to_str, validate_path
|
from apps.common.paths import address_n_to_str, validate_path
|
||||||
@ -103,6 +109,8 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
|
|||||||
):
|
):
|
||||||
mac = get_address_mac(address, coin.slip44, keychain)
|
mac = get_address_mac(address, coin.slip44, keychain)
|
||||||
|
|
||||||
|
response = Address(address=address, mac=mac)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
path = address_n_to_str(address_n)
|
path = address_n_to_str(address_n)
|
||||||
if multisig:
|
if multisig:
|
||||||
@ -156,4 +164,8 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
|
|||||||
chunkify=bool(msg.chunkify),
|
chunkify=bool(msg.chunkify),
|
||||||
)
|
)
|
||||||
|
|
||||||
return Address(address=address, mac=mac)
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return response
|
||||||
|
@ -5,6 +5,7 @@ if TYPE_CHECKING:
|
|||||||
from trezor.enums import InputScriptType
|
from trezor.enums import InputScriptType
|
||||||
from trezor.messages import GetPublicKey, PublicKey
|
from trezor.messages import GetPublicKey, PublicKey
|
||||||
from trezor.protobuf import MessageType
|
from trezor.protobuf import MessageType
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
@ -13,10 +14,11 @@ async def get_public_key(
|
|||||||
msg: GetPublicKey,
|
msg: GetPublicKey,
|
||||||
auth_msg: MessageType | None = None,
|
auth_msg: MessageType | None = None,
|
||||||
keychain: Keychain | None = None,
|
keychain: Keychain | None = None,
|
||||||
) -> PublicKey:
|
) -> MaybeEarlyResponse[PublicKey]:
|
||||||
from trezor import TR, wire
|
from trezor import TR, wire
|
||||||
from trezor.enums import InputScriptType
|
from trezor.enums import InputScriptType
|
||||||
from trezor.messages import HDNodeType, PublicKey, UnlockPath
|
from trezor.messages import HDNodeType, PublicKey, UnlockPath
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import coininfo, paths
|
from apps.common import coininfo, paths
|
||||||
from apps.common.keychain import FORBIDDEN_KEY_PATH, get_keychain
|
from apps.common.keychain import FORBIDDEN_KEY_PATH, get_keychain
|
||||||
@ -86,9 +88,19 @@ async def get_public_key(
|
|||||||
descriptor = _xpub_descriptor(
|
descriptor = _xpub_descriptor(
|
||||||
node, xpub_magic, address_n, script_type, keychain.root_fingerprint()
|
node, xpub_magic, address_n, script_type, keychain.root_fingerprint()
|
||||||
)
|
)
|
||||||
|
response = PublicKey(
|
||||||
|
node=node_type,
|
||||||
|
xpub=node_xpub,
|
||||||
|
root_fingerprint=keychain.root_fingerprint(),
|
||||||
|
descriptor=descriptor,
|
||||||
|
)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
from trezor.ui.layouts import confirm_path_warning, show_pubkey
|
from trezor.ui.layouts import (
|
||||||
|
confirm_path_warning,
|
||||||
|
show_continue_in_app,
|
||||||
|
show_pubkey,
|
||||||
|
)
|
||||||
|
|
||||||
from apps.common.paths import address_n_to_str
|
from apps.common.paths import address_n_to_str
|
||||||
|
|
||||||
@ -116,13 +128,11 @@ async def get_public_key(
|
|||||||
mismatch_title=TR.addr_mismatch__xpub_mismatch,
|
mismatch_title=TR.addr_mismatch__xpub_mismatch,
|
||||||
br_name="show_xpub",
|
br_name="show_xpub",
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
return PublicKey(
|
response, show_continue_in_app(TR.address__public_key_confirmed)
|
||||||
node=node_type,
|
)
|
||||||
xpub=node_xpub,
|
else:
|
||||||
root_fingerprint=keychain.root_fingerprint(),
|
return response
|
||||||
descriptor=descriptor,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _xpub_descriptor(
|
def _xpub_descriptor(
|
||||||
|
@ -21,6 +21,7 @@ if TYPE_CHECKING:
|
|||||||
VerifyMessage,
|
VerifyMessage,
|
||||||
)
|
)
|
||||||
from trezor.protobuf import MessageType
|
from trezor.protobuf import MessageType
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
from typing_extensions import Protocol
|
from typing_extensions import Protocol
|
||||||
|
|
||||||
from apps.common import coininfo
|
from apps.common import coininfo
|
||||||
@ -43,7 +44,7 @@ if TYPE_CHECKING:
|
|||||||
script_type: InputScriptType
|
script_type: InputScriptType
|
||||||
|
|
||||||
MsgIn = TypeVar("MsgIn", bound=BitcoinMessage)
|
MsgIn = TypeVar("MsgIn", bound=BitcoinMessage)
|
||||||
HandlerWithCoinInfo = Callable[..., Awaitable[MsgOut]]
|
HandlerWithCoinInfo = Callable[..., Awaitable[MaybeEarlyResponse[MsgOut]]]
|
||||||
|
|
||||||
# BIP-45 for multisig: https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki
|
# BIP-45 for multisig: https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki
|
||||||
PATTERN_BIP45 = "m/45'/[0-100]/change/address_index"
|
PATTERN_BIP45 = "m/45'/[0-100]/change/address_index"
|
||||||
@ -316,7 +317,7 @@ def with_keychain(func: HandlerWithCoinInfo[MsgOut]) -> Handler[MsgIn, MsgOut]:
|
|||||||
async def wrapper(
|
async def wrapper(
|
||||||
msg: BitcoinMessage,
|
msg: BitcoinMessage,
|
||||||
auth_msg: MessageType | None = None,
|
auth_msg: MessageType | None = None,
|
||||||
) -> MsgOut:
|
) -> MaybeEarlyResponse[MsgOut]:
|
||||||
coin = _get_coin_by_name(msg.coin_name)
|
coin = _get_coin_by_name(msg.coin_name)
|
||||||
unlock_schemas = _get_unlock_schemas(msg, auth_msg, coin)
|
unlock_schemas = _get_unlock_schemas(msg, auth_msg, coin)
|
||||||
keychain = await _get_keychain_for_coin(coin, unlock_schemas)
|
keychain = await _get_keychain_for_coin(coin, unlock_schemas)
|
||||||
|
@ -4,14 +4,17 @@ from . import seed
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import CardanoAddress, CardanoGetAddress
|
from trezor.messages import CardanoAddress, CardanoGetAddress
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
|
|
||||||
@seed.with_keychain
|
@seed.with_keychain
|
||||||
async def get_address(
|
async def get_address(
|
||||||
msg: CardanoGetAddress, keychain: seed.Keychain
|
msg: CardanoGetAddress, keychain: seed.Keychain
|
||||||
) -> CardanoAddress:
|
) -> MaybeEarlyResponse[CardanoAddress]:
|
||||||
from trezor import log, wire
|
from trezor import log, wire
|
||||||
from trezor.messages import CardanoAddress
|
from trezor.messages import CardanoAddress
|
||||||
|
from trezor.ui.layouts import show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from . import addresses
|
from . import addresses
|
||||||
from .helpers.credential import Credential, should_show_credentials
|
from .helpers.credential import Credential, should_show_credentials
|
||||||
@ -32,7 +35,11 @@ async def get_address(
|
|||||||
log.exception(__name__, e)
|
log.exception(__name__, e)
|
||||||
raise wire.ProcessError("Deriving address failed")
|
raise wire.ProcessError("Deriving address failed")
|
||||||
|
|
||||||
|
response = CardanoAddress(address=address)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
# _display_address
|
# _display_address
|
||||||
if should_show_credentials(address_parameters):
|
if should_show_credentials(address_parameters):
|
||||||
await show_credentials(
|
await show_credentials(
|
||||||
@ -42,5 +49,8 @@ async def get_address(
|
|||||||
await show_cardano_address(
|
await show_cardano_address(
|
||||||
address_parameters, address, msg.protocol_magic, chunkify=bool(msg.chunkify)
|
address_parameters, address, msg.protocol_magic, chunkify=bool(msg.chunkify)
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return CardanoAddress(address=address)
|
return response
|
||||||
|
@ -7,12 +7,13 @@ from . import seed
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import CardanoGetPublicKey, CardanoPublicKey
|
from trezor.messages import CardanoGetPublicKey, CardanoPublicKey
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
|
|
||||||
@seed.with_keychain
|
@seed.with_keychain
|
||||||
async def get_public_key(
|
async def get_public_key(
|
||||||
msg: CardanoGetPublicKey, keychain: seed.Keychain
|
msg: CardanoGetPublicKey, keychain: seed.Keychain
|
||||||
) -> CardanoPublicKey:
|
) -> MaybeEarlyResponse[CardanoPublicKey]:
|
||||||
from trezor import log, wire
|
from trezor import log, wire
|
||||||
from trezor.ui.layouts import show_pubkey
|
from trezor.ui.layouts import show_pubkey
|
||||||
|
|
||||||
@ -37,10 +38,17 @@ async def get_public_key(
|
|||||||
raise wire.ProcessError("Deriving public key failed")
|
raise wire.ProcessError("Deriving public key failed")
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor.ui.layouts import show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common.paths import address_n_to_str
|
from apps.common.paths import address_n_to_str
|
||||||
|
|
||||||
path = address_n_to_str(address_n)
|
path = address_n_to_str(address_n)
|
||||||
await show_pubkey(key.xpub, TR.address__public_key, path=path)
|
await show_pubkey(key.xpub, TR.address__public_key, path=path)
|
||||||
|
return await early_response(
|
||||||
|
key, show_continue_in_app(TR.address__public_key_confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ if TYPE_CHECKING:
|
|||||||
from trezor import messages
|
from trezor import messages
|
||||||
from trezor.crypto import bip32
|
from trezor.crypto import bip32
|
||||||
from trezor.enums import CardanoDerivationType
|
from trezor.enums import CardanoDerivationType
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Handler, MsgOut
|
from apps.common.keychain import Handler, MsgOut
|
||||||
from apps.common.paths import Bip32Path
|
from apps.common.paths import Bip32Path
|
||||||
@ -33,7 +34,9 @@ if TYPE_CHECKING:
|
|||||||
)
|
)
|
||||||
MsgIn = TypeVar("MsgIn", bound=CardanoMessages)
|
MsgIn = TypeVar("MsgIn", bound=CardanoMessages)
|
||||||
|
|
||||||
HandlerWithKeychain = Callable[[MsgIn, "Keychain"], Awaitable[MsgOut]]
|
HandlerWithKeychain = Callable[
|
||||||
|
[MsgIn, "Keychain"], Awaitable[MaybeEarlyResponse[MsgOut]]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Keychain:
|
class Keychain:
|
||||||
@ -183,7 +186,7 @@ async def _get_keychain(derivation_type: CardanoDerivationType) -> Keychain:
|
|||||||
|
|
||||||
|
|
||||||
def with_keychain(func: HandlerWithKeychain[MsgIn, MsgOut]) -> Handler[MsgIn, MsgOut]:
|
def with_keychain(func: HandlerWithKeychain[MsgIn, MsgOut]) -> Handler[MsgIn, MsgOut]:
|
||||||
async def wrapper(msg: MsgIn) -> MsgOut:
|
async def wrapper(msg: MsgIn) -> MaybeEarlyResponse[MsgOut]:
|
||||||
keychain = await _get_keychain(msg.derivation_type)
|
keychain = await _get_keychain(msg.derivation_type)
|
||||||
return await func(msg, keychain)
|
return await func(msg, keychain)
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ if TYPE_CHECKING:
|
|||||||
from typing import Any, Awaitable, Callable, Iterable, TypeVar
|
from typing import Any, Awaitable, Callable, Iterable, TypeVar
|
||||||
|
|
||||||
from trezor.protobuf import MessageType
|
from trezor.protobuf import MessageType
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
from typing_extensions import Protocol
|
from typing_extensions import Protocol
|
||||||
|
|
||||||
from .seed import Slip21Node
|
from .seed import Slip21Node
|
||||||
@ -27,8 +28,10 @@ if TYPE_CHECKING:
|
|||||||
MsgIn = TypeVar("MsgIn", bound=MessageType)
|
MsgIn = TypeVar("MsgIn", bound=MessageType)
|
||||||
MsgOut = TypeVar("MsgOut", bound=MessageType)
|
MsgOut = TypeVar("MsgOut", bound=MessageType)
|
||||||
|
|
||||||
Handler = Callable[[MsgIn], Awaitable[MsgOut]]
|
Handler = Callable[[MsgIn], Awaitable[MaybeEarlyResponse[MsgOut]]]
|
||||||
HandlerWithKeychain = Callable[[MsgIn, "Keychain"], Awaitable[MsgOut]]
|
HandlerWithKeychain = Callable[
|
||||||
|
[MsgIn, "Keychain"], Awaitable[MaybeEarlyResponse[MsgOut]]
|
||||||
|
]
|
||||||
|
|
||||||
class Deletable(Protocol):
|
class Deletable(Protocol):
|
||||||
def __del__(self) -> None: ...
|
def __del__(self) -> None: ...
|
||||||
@ -194,7 +197,7 @@ def with_slip44_keychain(
|
|||||||
schemas = [s.copy() for s in schemas]
|
schemas = [s.copy() for s in schemas]
|
||||||
|
|
||||||
def decorator(func: HandlerWithKeychain[MsgIn, MsgOut]) -> Handler[MsgIn, MsgOut]:
|
def decorator(func: HandlerWithKeychain[MsgIn, MsgOut]) -> Handler[MsgIn, MsgOut]:
|
||||||
async def wrapper(msg: MsgIn) -> MsgOut:
|
async def wrapper(msg: MsgIn) -> MaybeEarlyResponse[MsgOut]:
|
||||||
keychain = await get_keychain(curve, schemas)
|
keychain = await get_keychain(curve, schemas)
|
||||||
with keychain:
|
with keychain:
|
||||||
return await func(msg, keychain)
|
return await func(msg, keychain)
|
||||||
|
@ -4,14 +4,19 @@ from apps.common.keychain import auto_keychain
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import EosGetPublicKey, EosPublicKey
|
from trezor.messages import EosGetPublicKey, EosPublicKey
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
@auto_keychain(__name__)
|
||||||
async def get_public_key(msg: EosGetPublicKey, keychain: Keychain) -> EosPublicKey:
|
async def get_public_key(
|
||||||
|
msg: EosGetPublicKey, keychain: Keychain
|
||||||
|
) -> MaybeEarlyResponse[EosPublicKey]:
|
||||||
from trezor.crypto.curve import secp256k1
|
from trezor.crypto.curve import secp256k1
|
||||||
from trezor.messages import EosPublicKey
|
from trezor.messages import EosPublicKey
|
||||||
|
from trezor.ui.layouts import show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths
|
from apps.common import paths
|
||||||
|
|
||||||
@ -24,11 +29,18 @@ async def get_public_key(msg: EosGetPublicKey, keychain: Keychain) -> EosPublicK
|
|||||||
|
|
||||||
public_key = secp256k1.publickey(node.private_key(), True)
|
public_key = secp256k1.publickey(node.private_key(), True)
|
||||||
wif = public_key_to_wif(public_key)
|
wif = public_key_to_wif(public_key)
|
||||||
|
response = EosPublicKey(wif_public_key=wif, raw_public_key=public_key)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
from . import PATTERN, SLIP44_ID
|
from . import PATTERN, SLIP44_ID
|
||||||
|
|
||||||
path = paths.address_n_to_str(msg.address_n)
|
path = paths.address_n_to_str(msg.address_n)
|
||||||
account = paths.get_account_name("EOS", msg.address_n, PATTERN, SLIP44_ID)
|
account = paths.get_account_name("EOS", msg.address_n, PATTERN, SLIP44_ID)
|
||||||
await require_get_public_key(wif, path, account)
|
await require_get_public_key(wif, path, account)
|
||||||
return EosPublicKey(wif_public_key=wif, raw_public_key=public_key)
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__public_key_confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
|
return response
|
||||||
|
@ -4,6 +4,7 @@ from .keychain import PATTERNS_ADDRESS, with_keychain_from_path
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import EthereumAddress, EthereumGetAddress
|
from trezor.messages import EthereumAddress, EthereumGetAddress
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
@ -15,9 +16,10 @@ async def get_address(
|
|||||||
msg: EthereumGetAddress,
|
msg: EthereumGetAddress,
|
||||||
keychain: Keychain,
|
keychain: Keychain,
|
||||||
defs: Definitions,
|
defs: Definitions,
|
||||||
) -> EthereumAddress:
|
) -> MaybeEarlyResponse[EthereumAddress]:
|
||||||
from trezor.messages import EthereumAddress
|
from trezor.messages import EthereumAddress
|
||||||
from trezor.ui.layouts import show_address
|
from trezor.ui.layouts import show_address, show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths
|
from apps.common import paths
|
||||||
|
|
||||||
@ -30,8 +32,11 @@ async def get_address(
|
|||||||
node = keychain.derive(address_n)
|
node = keychain.derive(address_n)
|
||||||
|
|
||||||
address = address_from_bytes(node.ethereum_pubkeyhash(), defs.network)
|
address = address_from_bytes(node.ethereum_pubkeyhash(), defs.network)
|
||||||
|
response = EthereumAddress(address=address)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
slip44_id = address_n[1] # it depends on the network (ETH vs ETC...)
|
slip44_id = address_n[1] # it depends on the network (ETH vs ETC...)
|
||||||
await show_address(
|
await show_address(
|
||||||
address,
|
address,
|
||||||
@ -41,5 +46,8 @@ async def get_address(
|
|||||||
),
|
),
|
||||||
chunkify=bool(msg.chunkify),
|
chunkify=bool(msg.chunkify),
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return EthereumAddress(address=address)
|
return response
|
||||||
|
@ -2,21 +2,32 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import EthereumGetPublicKey, EthereumPublicKey
|
from trezor.messages import EthereumGetPublicKey, EthereumPublicKey
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
|
|
||||||
async def get_public_key(msg: EthereumGetPublicKey) -> EthereumPublicKey:
|
async def get_public_key(
|
||||||
|
msg: EthereumGetPublicKey,
|
||||||
|
) -> MaybeEarlyResponse[EthereumPublicKey]:
|
||||||
from ubinascii import hexlify
|
from ubinascii import hexlify
|
||||||
|
|
||||||
from trezor.messages import EthereumPublicKey, GetPublicKey
|
from trezor.messages import EthereumPublicKey, GetPublicKey, PublicKey
|
||||||
from trezor.ui.layouts import show_pubkey
|
from trezor.ui.layouts import show_continue_in_app, show_pubkey
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.bitcoin import get_public_key as bitcoin_get_public_key
|
from apps.bitcoin import get_public_key as bitcoin_get_public_key
|
||||||
|
|
||||||
# we use the Bitcoin format for Ethereum xpubs
|
# we use the Bitcoin format for Ethereum xpubs
|
||||||
btc_pubkey_msg = GetPublicKey(address_n=msg.address_n)
|
btc_pubkey_msg = GetPublicKey(address_n=msg.address_n, show_display=False)
|
||||||
resp = await bitcoin_get_public_key.get_public_key(btc_pubkey_msg)
|
btc_resp = await bitcoin_get_public_key.get_public_key(btc_pubkey_msg)
|
||||||
|
assert PublicKey.is_type_of(btc_resp)
|
||||||
|
|
||||||
|
response = EthereumPublicKey(node=btc_resp.node, xpub=btc_resp.xpub)
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
await show_pubkey(hexlify(resp.node.public_key).decode())
|
from trezor import TR
|
||||||
|
|
||||||
return EthereumPublicKey(node=resp.node, xpub=resp.xpub)
|
await show_pubkey(hexlify(response.node.public_key).decode())
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__public_key_confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
|
return response
|
||||||
|
@ -17,6 +17,7 @@ if TYPE_CHECKING:
|
|||||||
EthereumSignTxEIP1559,
|
EthereumSignTxEIP1559,
|
||||||
EthereumSignTypedData,
|
EthereumSignTypedData,
|
||||||
)
|
)
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Handler, Keychain, MsgOut
|
from apps.common.keychain import Handler, Keychain, MsgOut
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
HandlerAddressN = Callable[
|
HandlerAddressN = Callable[
|
||||||
[MsgInAddressN, Keychain, definitions.Definitions],
|
[MsgInAddressN, Keychain, definitions.Definitions],
|
||||||
Awaitable[MsgOut],
|
Awaitable[MaybeEarlyResponse[MsgOut]],
|
||||||
]
|
]
|
||||||
|
|
||||||
# messages for "with_keychain_and_defs_from_chain_id" decorator
|
# messages for "with_keychain_and_defs_from_chain_id" decorator
|
||||||
@ -42,7 +43,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
HandlerChainId = Callable[
|
HandlerChainId = Callable[
|
||||||
[MsgInSignTx, Keychain, definitions.Definitions],
|
[MsgInSignTx, Keychain, definitions.Definitions],
|
||||||
Awaitable[MsgOut],
|
Awaitable[MaybeEarlyResponse[MsgOut]],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ def with_keychain_from_path(
|
|||||||
def decorator(
|
def decorator(
|
||||||
func: HandlerAddressN[MsgInAddressN, MsgOut]
|
func: HandlerAddressN[MsgInAddressN, MsgOut]
|
||||||
) -> Handler[MsgInAddressN, MsgOut]:
|
) -> Handler[MsgInAddressN, MsgOut]:
|
||||||
async def wrapper(msg: MsgInAddressN) -> MsgOut:
|
async def wrapper(msg: MsgInAddressN) -> MaybeEarlyResponse[MsgOut]:
|
||||||
slip44 = _slip44_from_address_n(msg.address_n)
|
slip44 = _slip44_from_address_n(msg.address_n)
|
||||||
defs = _defs_from_message(msg, slip44=slip44)
|
defs = _defs_from_message(msg, slip44=slip44)
|
||||||
schemas = _schemas_from_network(patterns, defs.network)
|
schemas = _schemas_from_network(patterns, defs.network)
|
||||||
@ -137,7 +138,7 @@ def with_keychain_from_chain_id(
|
|||||||
func: HandlerChainId[MsgInSignTx, MsgOut]
|
func: HandlerChainId[MsgInSignTx, MsgOut]
|
||||||
) -> Handler[MsgInSignTx, MsgOut]:
|
) -> Handler[MsgInSignTx, MsgOut]:
|
||||||
# this is only for SignTx, and only PATTERN_ADDRESS is allowed
|
# this is only for SignTx, and only PATTERN_ADDRESS is allowed
|
||||||
async def wrapper(msg: MsgInSignTx) -> MsgOut:
|
async def wrapper(msg: MsgInSignTx) -> MaybeEarlyResponse[MsgOut]:
|
||||||
defs = _defs_from_message(msg, chain_id=msg.chain_id)
|
defs = _defs_from_message(msg, chain_id=msg.chain_id)
|
||||||
schemas = _schemas_from_network(PATTERNS_ADDRESS, defs.network)
|
schemas = _schemas_from_network(PATTERNS_ADDRESS, defs.network)
|
||||||
keychain = await get_keychain(CURVE, schemas)
|
keychain = await get_keychain(CURVE, schemas)
|
||||||
|
@ -100,7 +100,7 @@ async def show_dry_run_result(result: bool, is_slip39: bool) -> None:
|
|||||||
text = TR.recovery__dry_run_slip39_valid_match
|
text = TR.recovery__dry_run_slip39_valid_match
|
||||||
else:
|
else:
|
||||||
text = TR.recovery__dry_run_bip39_valid_match
|
text = TR.recovery__dry_run_bip39_valid_match
|
||||||
await show_success("success_dry_recovery", text, button=TR.buttons__continue)
|
await show_success("success_dry_recovery", text)
|
||||||
else:
|
else:
|
||||||
if is_slip39:
|
if is_slip39:
|
||||||
text = TR.recovery__dry_run_slip39_valid_mismatch
|
text = TR.recovery__dry_run_slip39_valid_mismatch
|
||||||
|
@ -144,7 +144,12 @@ async def reset_device(msg: ResetDevice) -> Success:
|
|||||||
|
|
||||||
async def _entropy_check(secret: bytes) -> bool:
|
async def _entropy_check(secret: bytes) -> bool:
|
||||||
"""Returns True to indicate that entropy check loop should end."""
|
"""Returns True to indicate that entropy check loop should end."""
|
||||||
from trezor.messages import EntropyCheckContinue, EntropyCheckReady, GetPublicKey
|
from trezor.messages import (
|
||||||
|
EntropyCheckContinue,
|
||||||
|
EntropyCheckReady,
|
||||||
|
GetPublicKey,
|
||||||
|
PublicKey,
|
||||||
|
)
|
||||||
from trezor.wire.context import call_any
|
from trezor.wire.context import call_any
|
||||||
|
|
||||||
from apps.bitcoin.get_public_key import get_public_key
|
from apps.bitcoin.get_public_key import get_public_key
|
||||||
@ -171,6 +176,7 @@ async def _entropy_check(secret: bytes) -> bool:
|
|||||||
curve_name = req.ecdsa_curve_name or coininfo.by_name(req.coin_name).curve_name
|
curve_name = req.ecdsa_curve_name or coininfo.by_name(req.coin_name).curve_name
|
||||||
keychain = Keychain(seed, curve_name, [paths.AlwaysMatchingSchema])
|
keychain = Keychain(seed, curve_name, [paths.AlwaysMatchingSchema])
|
||||||
msg = await get_public_key(req, keychain=keychain)
|
msg = await get_public_key(req, keychain=keychain)
|
||||||
|
assert PublicKey.is_type_of(msg)
|
||||||
|
|
||||||
|
|
||||||
async def _backup_bip39(mnemonic: str) -> None:
|
async def _backup_bip39(mnemonic: str) -> None:
|
||||||
|
@ -4,15 +4,19 @@ from apps.common.keychain import auto_keychain
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import MoneroAddress, MoneroGetAddress
|
from trezor.messages import MoneroAddress, MoneroGetAddress
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
@auto_keychain(__name__)
|
||||||
async def get_address(msg: MoneroGetAddress, keychain: Keychain) -> MoneroAddress:
|
async def get_address(
|
||||||
|
msg: MoneroGetAddress, keychain: Keychain
|
||||||
|
) -> MaybeEarlyResponse[MoneroAddress]:
|
||||||
from trezor import wire
|
from trezor import wire
|
||||||
from trezor.messages import MoneroAddress
|
from trezor.messages import MoneroAddress
|
||||||
from trezor.ui.layouts import show_address
|
from trezor.ui.layouts import show_address, show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths
|
from apps.common import paths
|
||||||
from apps.monero import misc
|
from apps.monero import misc
|
||||||
@ -65,7 +69,11 @@ async def get_address(msg: MoneroGetAddress, keychain: Keychain) -> MoneroAddres
|
|||||||
crypto_helpers.encodepoint(pub_view),
|
crypto_helpers.encodepoint(pub_view),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
response = MoneroAddress(address=addr.encode())
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
from . import PATTERN, SLIP44_ID
|
from . import PATTERN, SLIP44_ID
|
||||||
|
|
||||||
await show_address(
|
await show_address(
|
||||||
@ -75,5 +83,8 @@ async def get_address(msg: MoneroGetAddress, keychain: Keychain) -> MoneroAddres
|
|||||||
account=paths.get_account_name("XMR", msg.address_n, PATTERN, SLIP44_ID),
|
account=paths.get_account_name("XMR", msg.address_n, PATTERN, SLIP44_ID),
|
||||||
chunkify=bool(msg.chunkify),
|
chunkify=bool(msg.chunkify),
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return MoneroAddress(address=addr.encode())
|
return response
|
||||||
|
@ -6,14 +6,18 @@ from . import CURVE, PATTERNS, SLIP44_ID
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import NEMAddress, NEMGetAddress
|
from trezor.messages import NEMAddress, NEMGetAddress
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||||
async def get_address(msg: NEMGetAddress, keychain: Keychain) -> NEMAddress:
|
async def get_address(
|
||||||
|
msg: NEMGetAddress, keychain: Keychain
|
||||||
|
) -> MaybeEarlyResponse[NEMAddress]:
|
||||||
from trezor.messages import NEMAddress
|
from trezor.messages import NEMAddress
|
||||||
from trezor.ui.layouts import show_address
|
from trezor.ui.layouts import show_address, show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths
|
from apps.common import paths
|
||||||
|
|
||||||
@ -28,8 +32,11 @@ async def get_address(msg: NEMGetAddress, keychain: Keychain) -> NEMAddress:
|
|||||||
|
|
||||||
node = keychain.derive(address_n)
|
node = keychain.derive(address_n)
|
||||||
address = node.nem_address(network)
|
address = node.nem_address(network)
|
||||||
|
response = NEMAddress(address=address)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
from . import PATTERNS, SLIP44_ID
|
from . import PATTERNS, SLIP44_ID
|
||||||
|
|
||||||
await show_address(
|
await show_address(
|
||||||
@ -40,5 +47,8 @@ async def get_address(msg: NEMGetAddress, keychain: Keychain) -> NEMAddress:
|
|||||||
network=get_network_str(network),
|
network=get_network_str(network),
|
||||||
chunkify=bool(msg.chunkify),
|
chunkify=bool(msg.chunkify),
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return NEMAddress(address=address)
|
return response
|
||||||
|
@ -4,15 +4,19 @@ from apps.common.keychain import auto_keychain
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import RippleAddress, RippleGetAddress
|
from trezor.messages import RippleAddress, RippleGetAddress
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
@auto_keychain(__name__)
|
||||||
async def get_address(msg: RippleGetAddress, keychain: Keychain) -> RippleAddress:
|
async def get_address(
|
||||||
|
msg: RippleGetAddress, keychain: Keychain
|
||||||
|
) -> MaybeEarlyResponse[RippleAddress]:
|
||||||
# NOTE: local imports here saves 20 bytes
|
# NOTE: local imports here saves 20 bytes
|
||||||
from trezor.messages import RippleAddress
|
from trezor.messages import RippleAddress
|
||||||
from trezor.ui.layouts import show_address
|
from trezor.ui.layouts import show_address, show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths
|
from apps.common import paths
|
||||||
|
|
||||||
@ -25,8 +29,11 @@ async def get_address(msg: RippleGetAddress, keychain: Keychain) -> RippleAddres
|
|||||||
node = keychain.derive(address_n)
|
node = keychain.derive(address_n)
|
||||||
pubkey = node.public_key()
|
pubkey = node.public_key()
|
||||||
address = address_from_public_key(pubkey)
|
address = address_from_public_key(pubkey)
|
||||||
|
response = RippleAddress(address=address)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
from . import PATTERN, SLIP44_ID
|
from . import PATTERN, SLIP44_ID
|
||||||
|
|
||||||
await show_address(
|
await show_address(
|
||||||
@ -35,5 +42,8 @@ async def get_address(msg: RippleGetAddress, keychain: Keychain) -> RippleAddres
|
|||||||
account=paths.get_account_name("XRP", msg.address_n, PATTERN, SLIP44_ID),
|
account=paths.get_account_name("XRP", msg.address_n, PATTERN, SLIP44_ID),
|
||||||
chunkify=bool(msg.chunkify),
|
chunkify=bool(msg.chunkify),
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return RippleAddress(address=address)
|
return response
|
||||||
|
@ -8,6 +8,7 @@ from . import CURVE, PATTERNS, SLIP44_ID
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import SolanaAddress, SolanaGetAddress
|
from trezor.messages import SolanaAddress, SolanaGetAddress
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
@ -16,9 +17,10 @@ if TYPE_CHECKING:
|
|||||||
async def get_address(
|
async def get_address(
|
||||||
msg: SolanaGetAddress,
|
msg: SolanaGetAddress,
|
||||||
keychain: Keychain,
|
keychain: Keychain,
|
||||||
) -> SolanaAddress:
|
) -> MaybeEarlyResponse[SolanaAddress]:
|
||||||
from trezor.messages import SolanaAddress
|
from trezor.messages import SolanaAddress
|
||||||
from trezor.ui.layouts import show_address
|
from trezor.ui.layouts import show_address, show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths
|
from apps.common import paths
|
||||||
|
|
||||||
@ -26,12 +28,18 @@ async def get_address(
|
|||||||
|
|
||||||
public_key = derive_public_key(keychain, msg.address_n)
|
public_key = derive_public_key(keychain, msg.address_n)
|
||||||
address = base58.encode(public_key)
|
address = base58.encode(public_key)
|
||||||
|
response = SolanaAddress(address=address)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
await show_address(
|
await show_address(
|
||||||
address,
|
address,
|
||||||
path=paths.address_n_to_str(msg.address_n),
|
path=paths.address_n_to_str(msg.address_n),
|
||||||
chunkify=bool(msg.chunkify),
|
chunkify=bool(msg.chunkify),
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return SolanaAddress(address=address)
|
return response
|
||||||
|
@ -9,6 +9,7 @@ from . import CURVE, PATTERNS, SLIP44_ID
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import SolanaGetPublicKey, SolanaPublicKey
|
from trezor.messages import SolanaGetPublicKey, SolanaPublicKey
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
@ -16,19 +17,26 @@ if TYPE_CHECKING:
|
|||||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||||
async def get_public_key(
|
async def get_public_key(
|
||||||
msg: SolanaGetPublicKey, keychain: Keychain
|
msg: SolanaGetPublicKey, keychain: Keychain
|
||||||
) -> SolanaPublicKey:
|
) -> MaybeEarlyResponse[SolanaPublicKey]:
|
||||||
from trezor.messages import SolanaPublicKey
|
from trezor.messages import SolanaPublicKey
|
||||||
from trezor.ui.layouts import show_pubkey
|
from trezor.ui.layouts import show_continue_in_app, show_pubkey
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
public_key = derive_public_key(keychain, msg.address_n)
|
public_key = derive_public_key(keychain, msg.address_n)
|
||||||
|
response = SolanaPublicKey(public_key=public_key)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
from apps.common.paths import address_n_to_str
|
from apps.common.paths import address_n_to_str
|
||||||
|
|
||||||
path = address_n_to_str(msg.address_n)
|
path = address_n_to_str(msg.address_n)
|
||||||
await show_pubkey(base58.encode(public_key), path=path)
|
await show_pubkey(base58.encode(public_key), path=path)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__public_key_confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return SolanaPublicKey(public_key=public_key)
|
return response
|
||||||
|
|
||||||
|
|
||||||
def derive_public_key(keychain: Keychain, address_n: list[int]) -> bytes:
|
def derive_public_key(keychain: Keychain, address_n: list[int]) -> bytes:
|
||||||
|
@ -4,14 +4,18 @@ from apps.common.keychain import auto_keychain
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import StellarAddress, StellarGetAddress
|
from trezor.messages import StellarAddress, StellarGetAddress
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
@auto_keychain(__name__)
|
||||||
async def get_address(msg: StellarGetAddress, keychain: Keychain) -> StellarAddress:
|
async def get_address(
|
||||||
|
msg: StellarGetAddress, keychain: Keychain
|
||||||
|
) -> MaybeEarlyResponse[StellarAddress]:
|
||||||
from trezor.messages import StellarAddress
|
from trezor.messages import StellarAddress
|
||||||
from trezor.ui.layouts import show_address
|
from trezor.ui.layouts import show_address, show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths, seed
|
from apps.common import paths, seed
|
||||||
|
|
||||||
@ -24,8 +28,11 @@ async def get_address(msg: StellarGetAddress, keychain: Keychain) -> StellarAddr
|
|||||||
node = keychain.derive(address_n)
|
node = keychain.derive(address_n)
|
||||||
pubkey = seed.remove_ed25519_prefix(node.public_key())
|
pubkey = seed.remove_ed25519_prefix(node.public_key())
|
||||||
address = helpers.address_from_public_key(pubkey)
|
address = helpers.address_from_public_key(pubkey)
|
||||||
|
response = StellarAddress(address=address)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
from . import PATTERN, SLIP44_ID
|
from . import PATTERN, SLIP44_ID
|
||||||
|
|
||||||
await show_address(
|
await show_address(
|
||||||
@ -35,5 +42,8 @@ async def get_address(msg: StellarGetAddress, keychain: Keychain) -> StellarAddr
|
|||||||
account=paths.get_account_name("XLM", msg.address_n, PATTERN, SLIP44_ID),
|
account=paths.get_account_name("XLM", msg.address_n, PATTERN, SLIP44_ID),
|
||||||
chunkify=bool(msg.chunkify),
|
chunkify=bool(msg.chunkify),
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return StellarAddress(address=address)
|
return response
|
||||||
|
@ -6,15 +6,19 @@ from . import CURVE, PATTERNS, SLIP44_ID
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import TezosAddress, TezosGetAddress
|
from trezor.messages import TezosAddress, TezosGetAddress
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||||
async def get_address(msg: TezosGetAddress, keychain: Keychain) -> TezosAddress:
|
async def get_address(
|
||||||
|
msg: TezosGetAddress, keychain: Keychain
|
||||||
|
) -> MaybeEarlyResponse[TezosAddress]:
|
||||||
from trezor.crypto import hashlib
|
from trezor.crypto import hashlib
|
||||||
from trezor.messages import TezosAddress
|
from trezor.messages import TezosAddress
|
||||||
from trezor.ui.layouts import show_address
|
from trezor.ui.layouts import show_address, show_continue_in_app
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths, seed
|
from apps.common import paths, seed
|
||||||
|
|
||||||
@ -29,8 +33,11 @@ async def get_address(msg: TezosGetAddress, keychain: Keychain) -> TezosAddress:
|
|||||||
pk = seed.remove_ed25519_prefix(node.public_key())
|
pk = seed.remove_ed25519_prefix(node.public_key())
|
||||||
pkh = hashlib.blake2b(pk, outlen=helpers.PUBLIC_KEY_HASH_SIZE).digest()
|
pkh = hashlib.blake2b(pk, outlen=helpers.PUBLIC_KEY_HASH_SIZE).digest()
|
||||||
address = helpers.base58_encode_check(pkh, helpers.TEZOS_ED25519_ADDRESS_PREFIX)
|
address = helpers.base58_encode_check(pkh, helpers.TEZOS_ED25519_ADDRESS_PREFIX)
|
||||||
|
response = TezosAddress(address=address)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
from . import PATTERNS, SLIP44_ID
|
from . import PATTERNS, SLIP44_ID
|
||||||
|
|
||||||
await show_address(
|
await show_address(
|
||||||
@ -39,5 +46,8 @@ async def get_address(msg: TezosGetAddress, keychain: Keychain) -> TezosAddress:
|
|||||||
account=paths.get_account_name("XTZ", address_n, PATTERNS, SLIP44_ID),
|
account=paths.get_account_name("XTZ", address_n, PATTERNS, SLIP44_ID),
|
||||||
chunkify=bool(msg.chunkify),
|
chunkify=bool(msg.chunkify),
|
||||||
)
|
)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return TezosAddress(address=address)
|
return response
|
||||||
|
@ -6,14 +6,18 @@ from . import CURVE, PATTERNS, SLIP44_ID
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import TezosGetPublicKey, TezosPublicKey
|
from trezor.messages import TezosGetPublicKey, TezosPublicKey
|
||||||
|
from trezor.wire import MaybeEarlyResponse
|
||||||
|
|
||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||||
async def get_public_key(msg: TezosGetPublicKey, keychain: Keychain) -> TezosPublicKey:
|
async def get_public_key(
|
||||||
|
msg: TezosGetPublicKey, keychain: Keychain
|
||||||
|
) -> MaybeEarlyResponse[TezosPublicKey]:
|
||||||
from trezor.messages import TezosPublicKey
|
from trezor.messages import TezosPublicKey
|
||||||
from trezor.ui.layouts import show_pubkey
|
from trezor.ui.layouts import show_continue_in_app, show_pubkey
|
||||||
|
from trezor.wire import early_response
|
||||||
|
|
||||||
from apps.common import paths, seed
|
from apps.common import paths, seed
|
||||||
|
|
||||||
@ -24,12 +28,18 @@ async def get_public_key(msg: TezosGetPublicKey, keychain: Keychain) -> TezosPub
|
|||||||
node = keychain.derive(msg.address_n)
|
node = keychain.derive(msg.address_n)
|
||||||
pk = seed.remove_ed25519_prefix(node.public_key())
|
pk = seed.remove_ed25519_prefix(node.public_key())
|
||||||
pk_prefixed = helpers.base58_encode_check(pk, helpers.TEZOS_PUBLICKEY_PREFIX)
|
pk_prefixed = helpers.base58_encode_check(pk, helpers.TEZOS_PUBLICKEY_PREFIX)
|
||||||
|
response = TezosPublicKey(public_key=pk_prefixed)
|
||||||
|
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
|
from trezor import TR
|
||||||
|
|
||||||
from . import PATTERNS, SLIP44_ID
|
from . import PATTERNS, SLIP44_ID
|
||||||
|
|
||||||
account = paths.get_account_name("XTZ", msg.address_n, PATTERNS, SLIP44_ID)
|
account = paths.get_account_name("XTZ", msg.address_n, PATTERNS, SLIP44_ID)
|
||||||
path = paths.address_n_to_str(msg.address_n)
|
path = paths.address_n_to_str(msg.address_n)
|
||||||
await show_pubkey(pk_prefixed, account=account, path=path)
|
await show_pubkey(pk_prefixed, account=account, path=path)
|
||||||
|
return await early_response(
|
||||||
|
response, show_continue_in_app(TR.address__public_key_confirmed)
|
||||||
|
)
|
||||||
|
|
||||||
return TezosPublicKey(public_key=pk_prefixed)
|
return response
|
||||||
|
@ -401,6 +401,10 @@ def show_success(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def show_continue_in_app(content: str) -> None:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
async def confirm_output(
|
async def confirm_output(
|
||||||
address: str,
|
address: str,
|
||||||
amount: str,
|
amount: str,
|
||||||
|
@ -464,6 +464,10 @@ def show_success(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def show_continue_in_app(content: str) -> None:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
async def confirm_output(
|
async def confirm_output(
|
||||||
address: str,
|
address: str,
|
||||||
amount: str,
|
amount: str,
|
||||||
|
@ -235,12 +235,6 @@ async def show_address(
|
|||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
title_success = (
|
|
||||||
TR.address__public_key_confirmed
|
|
||||||
if title in ("XPUB", TR.address__public_key)
|
|
||||||
else TR.address__confirmed
|
|
||||||
)
|
|
||||||
|
|
||||||
await raise_if_not_confirmed(
|
await raise_if_not_confirmed(
|
||||||
trezorui_api.flow_get_address(
|
trezorui_api.flow_get_address(
|
||||||
address=address,
|
address=address,
|
||||||
@ -253,7 +247,6 @@ async def show_address(
|
|||||||
account=account,
|
account=account,
|
||||||
path=path,
|
path=path,
|
||||||
xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
|
xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
|
||||||
title_success=title_success,
|
|
||||||
br_name=br_name,
|
br_name=br_name,
|
||||||
br_code=br_code,
|
br_code=br_code,
|
||||||
),
|
),
|
||||||
@ -349,22 +342,33 @@ def show_danger(
|
|||||||
|
|
||||||
|
|
||||||
def show_success(
|
def show_success(
|
||||||
br_name: str,
|
br_name: str | None,
|
||||||
content: str,
|
content: str,
|
||||||
subheader: str | None = None,
|
subheader: str | None = None,
|
||||||
button: str | None = None,
|
button: str | None = None,
|
||||||
|
time_ms: int = 0,
|
||||||
) -> Awaitable[None]:
|
) -> Awaitable[None]:
|
||||||
return raise_if_not_confirmed(
|
return raise_if_not_confirmed(
|
||||||
trezorui_api.show_success(
|
trezorui_api.show_success(
|
||||||
title=content,
|
title=content,
|
||||||
button="",
|
button=button or "",
|
||||||
description=subheader if subheader else "",
|
description=subheader or "",
|
||||||
|
time_ms=time_ms,
|
||||||
),
|
),
|
||||||
br_name,
|
br_name,
|
||||||
ButtonRequestType.Success,
|
ButtonRequestType.Success,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def show_continue_in_app(content: str) -> Awaitable[None]:
|
||||||
|
return show_success(
|
||||||
|
content=content,
|
||||||
|
button=TR.instructions__continue_in_app,
|
||||||
|
time_ms=3200,
|
||||||
|
br_name=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_output(
|
async def confirm_output(
|
||||||
address: str,
|
address: str,
|
||||||
amount: str | None = None,
|
amount: str | None = None,
|
||||||
|
@ -41,7 +41,7 @@ if __debug__:
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezorio import WireInterface
|
from trezorio import WireInterface
|
||||||
from typing import Any, Callable, Coroutine, TypeVar
|
from typing import Any, Awaitable, Callable, Coroutine, Generic, TypeAlias, TypeVar
|
||||||
|
|
||||||
Msg = TypeVar("Msg", bound=protobuf.MessageType)
|
Msg = TypeVar("Msg", bound=protobuf.MessageType)
|
||||||
HandlerTask = Coroutine[Any, Any, protobuf.MessageType]
|
HandlerTask = Coroutine[Any, Any, protobuf.MessageType]
|
||||||
@ -49,6 +49,28 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
LoadedMessageType = TypeVar("LoadedMessageType", bound=protobuf.MessageType)
|
LoadedMessageType = TypeVar("LoadedMessageType", bound=protobuf.MessageType)
|
||||||
|
|
||||||
|
class EarlyResponse(Generic[Msg]):
|
||||||
|
"""Marker type (when the response is sent before the last layout is shown)."""
|
||||||
|
|
||||||
|
MaybeEarlyResponse: TypeAlias = Msg | EarlyResponse[Msg]
|
||||||
|
|
||||||
|
else:
|
||||||
|
EarlyResponse = object
|
||||||
|
|
||||||
|
|
||||||
|
_EARLY_RESPONSE = EarlyResponse()
|
||||||
|
|
||||||
|
|
||||||
|
async def early_response(response: Msg, layout: Awaitable[None]) -> EarlyResponse[Msg]:
|
||||||
|
from .context import get_context
|
||||||
|
|
||||||
|
# first, send the response back to the client
|
||||||
|
await get_context().write(response)
|
||||||
|
# then, show the success layout
|
||||||
|
await layout
|
||||||
|
# return a special marker object
|
||||||
|
return _EARLY_RESPONSE
|
||||||
|
|
||||||
|
|
||||||
class BufferProvider:
|
class BufferProvider:
|
||||||
def __init__(self, size: int) -> None:
|
def __init__(self, size: int) -> None:
|
||||||
|
@ -63,6 +63,8 @@ async def handle_single_message(ctx: Context, msg: Message) -> bool:
|
|||||||
the type of message is supposed to be optimized and not disrupt the running state,
|
the type of message is supposed to be optimized and not disrupt the running state,
|
||||||
this function will return `True`.
|
this function will return `True`.
|
||||||
"""
|
"""
|
||||||
|
from . import _EARLY_RESPONSE
|
||||||
|
|
||||||
if __debug__:
|
if __debug__:
|
||||||
try:
|
try:
|
||||||
msg_type = protobuf.type_for_wire(msg.type).MESSAGE_NAME
|
msg_type = protobuf.type_for_wire(msg.type).MESSAGE_NAME
|
||||||
@ -75,8 +77,6 @@ async def handle_single_message(ctx: Context, msg: Message) -> bool:
|
|||||||
msg_type,
|
msg_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
res_msg: protobuf.MessageType | None = None
|
|
||||||
|
|
||||||
# We need to find a handler for this message type.
|
# We need to find a handler for this message type.
|
||||||
try:
|
try:
|
||||||
handler: Handler = find_handler(ctx.iface, msg.type)
|
handler: Handler = find_handler(ctx.iface, msg.type)
|
||||||
@ -159,7 +159,7 @@ async def handle_single_message(ctx: Context, msg: Message) -> bool:
|
|||||||
wire_log.exception(__name__, ctx.iface, exc)
|
wire_log.exception(__name__, ctx.iface, exc)
|
||||||
res_msg = failure(exc)
|
res_msg = failure(exc)
|
||||||
|
|
||||||
if res_msg is not None:
|
if res_msg is not _EARLY_RESPONSE:
|
||||||
# perform the write outside the big try-except block, so that usb write
|
# perform the write outside the big try-except block, so that usb write
|
||||||
# problem bubbles up
|
# problem bubbles up
|
||||||
await ctx.write(res_msg)
|
await ctx.write(res_msg)
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user