mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-09 11:55:58 +00:00
feat(core): send address & public key response before showing StatusScreen
This commit is contained in:
parent
08bcedcaa5
commit
a9ed3f31fc
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.
|
@ -689,7 +689,6 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_time_ms;
|
||||
MP_QSTR_timer;
|
||||
MP_QSTR_title;
|
||||
MP_QSTR_title_success;
|
||||
MP_QSTR_total_fee_new;
|
||||
MP_QSTR_total_len;
|
||||
MP_QSTR_touch_event;
|
||||
|
@ -532,7 +532,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 path: Option<TString> = kwargs.get(Qstr::MP_QSTR_path)?.try_into_option()?;
|
||||
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_name: TString = kwargs.get(Qstr::MP_QSTR_br_name)?.try_into()?;
|
||||
|
||||
@ -547,7 +546,6 @@ extern "C" fn new_flow_get_address(n_args: usize, args: *const Obj, kwargs: *mut
|
||||
account,
|
||||
path,
|
||||
xpubs,
|
||||
title_success,
|
||||
br_code,
|
||||
br_name,
|
||||
)?;
|
||||
@ -1401,7 +1399,6 @@ pub static mp_module_trezorui_api: Module = obj_module! {
|
||||
/// account: str | None,
|
||||
/// path: str | None,
|
||||
/// xpubs: list[tuple[str, str]],
|
||||
/// title_success: str,
|
||||
/// br_code: ButtonRequestType,
|
||||
/// br_name: str,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
|
@ -599,7 +599,6 @@ impl FirmwareUI for UIBolt {
|
||||
_account: Option<TString<'static>>,
|
||||
_path: Option<TString<'static>>,
|
||||
_xpubs: Obj,
|
||||
_title_success: TString<'static>,
|
||||
_br_code: u16,
|
||||
_br_name: TString<'static>,
|
||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||
|
@ -729,7 +729,6 @@ impl FirmwareUI for UICaesar {
|
||||
_account: Option<TString<'static>>,
|
||||
_path: Option<TString<'static>>,
|
||||
_xpubs: Obj,
|
||||
_title_success: TString<'static>,
|
||||
_br_code: u16,
|
||||
_br_name: TString<'static>,
|
||||
) -> 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(
|
||||
theme::ICON_SIMPLE_CHECKMARK30,
|
||||
theme::GREEN_LIME,
|
||||
theme::GREEN_LIGHT,
|
||||
DismissType::Timeout(Timeout::new(TIMEOUT_MS)),
|
||||
DismissType::Timeout(Timeout::new(time_ms)),
|
||||
msg,
|
||||
)
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::super::{
|
||||
component::{AddressDetails, Frame, PromptScreen, StatusScreen, SwipeContent, VerticalMenu},
|
||||
component::{AddressDetails, Frame, PromptScreen, SwipeContent, VerticalMenu},
|
||||
theme,
|
||||
};
|
||||
|
||||
@ -30,7 +30,6 @@ const QR_BORDER: i16 = 4;
|
||||
pub enum GetAddress {
|
||||
Address,
|
||||
Tap,
|
||||
Confirmed,
|
||||
Menu,
|
||||
QrCode,
|
||||
AccountInfo,
|
||||
@ -64,9 +63,8 @@ impl FlowController for GetAddress {
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(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::Confirmed, _) => self.return_msg(FlowMsg::Confirmed),
|
||||
(Self::Menu, FlowMsg::Choice(0)) => Self::QrCode.swipe_left(),
|
||||
(Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(),
|
||||
(Self::Menu, FlowMsg::Choice(2)) => Self::Cancel.swipe_left(),
|
||||
@ -93,7 +91,6 @@ pub fn new_get_address(
|
||||
account: Option<TString<'static>>,
|
||||
path: Option<TString<'static>>,
|
||||
xpubs: Obj, // TODO: get rid of Obj
|
||||
title_success: TString<'static>,
|
||||
br_code: u16,
|
||||
br_name: TString<'static>,
|
||||
) -> Result<SwipeFlow, error::Error> {
|
||||
@ -131,14 +128,6 @@ pub fn new_get_address(
|
||||
.with_swipe(Direction::Left, SwipeSettings::default())
|
||||
.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
|
||||
let content_menu = Frame::left_aligned(
|
||||
"".into(),
|
||||
@ -200,7 +189,6 @@ pub fn new_get_address(
|
||||
let mut res = SwipeFlow::new(&GetAddress::Address)?;
|
||||
res.add_page(&GetAddress::Address, content_address)?
|
||||
.add_page(&GetAddress::Tap, content_tap)?
|
||||
.add_page(&GetAddress::Confirmed, content_confirmed)?
|
||||
.add_page(&GetAddress::Menu, content_menu)?
|
||||
.add_page(&GetAddress::QrCode, content_qr)?
|
||||
.add_page(&GetAddress::AccountInfo, content_account)?
|
||||
|
@ -9,6 +9,7 @@ use crate::{
|
||||
ui::{
|
||||
component::{
|
||||
connect::Connect,
|
||||
swipe_detect::SwipeSettings,
|
||||
text::{
|
||||
op::OpTextLayout,
|
||||
paragraphs::{
|
||||
@ -19,7 +20,7 @@ use crate::{
|
||||
},
|
||||
Border, CachedJpeg, ComponentExt, Empty, FormattedText, Never, Timeout,
|
||||
},
|
||||
geometry::{self, Offset},
|
||||
geometry::{self, Direction, Offset},
|
||||
layout::{
|
||||
obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
||||
util::{PropsList, RecoveryType},
|
||||
@ -625,7 +626,6 @@ impl FirmwareUI for UIDelizia {
|
||||
account: Option<TString<'static>>,
|
||||
path: Option<TString<'static>>,
|
||||
xpubs: Obj,
|
||||
title_success: TString<'static>,
|
||||
br_code: u16,
|
||||
br_name: TString<'static>,
|
||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||
@ -640,7 +640,6 @@ impl FirmwareUI for UIDelizia {
|
||||
account,
|
||||
path,
|
||||
xpubs,
|
||||
title_success,
|
||||
br_code,
|
||||
br_name,
|
||||
)?;
|
||||
@ -1046,24 +1045,34 @@ impl FirmwareUI for UIDelizia {
|
||||
|
||||
fn show_success(
|
||||
title: TString<'static>,
|
||||
_button: TString<'static>,
|
||||
button: TString<'static>,
|
||||
description: TString<'static>,
|
||||
_allow_cancel: bool,
|
||||
_time_ms: u32,
|
||||
time_ms: u32,
|
||||
) -> Result<Gc<LayoutObj>, Error> {
|
||||
let instruction = if button.is_empty() {
|
||||
TR::instructions__tap_to_continue.into()
|
||||
} else {
|
||||
button
|
||||
};
|
||||
// description used in the Footer
|
||||
let description = if description.is_empty() {
|
||||
None
|
||||
} else {
|
||||
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(
|
||||
Frame::left_aligned(
|
||||
TR::words__title_success.into(),
|
||||
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),
|
||||
))?;
|
||||
Ok(layout)
|
||||
|
@ -200,7 +200,6 @@ pub trait FirmwareUI {
|
||||
account: Option<TString<'static>>,
|
||||
path: Option<TString<'static>>,
|
||||
xpubs: Obj, // TODO: replace Obj
|
||||
title_success: TString<'static>,
|
||||
br_code: u16,
|
||||
br_name: TString<'static>,
|
||||
) -> Result<impl LayoutMaybeTrace, Error>;
|
||||
|
@ -360,7 +360,6 @@ def flow_get_address(
|
||||
account: str | None,
|
||||
path: str | None,
|
||||
xpubs: list[tuple[str, str]],
|
||||
title_success: str,
|
||||
br_code: ButtonRequestType,
|
||||
br_name: str,
|
||||
) -> LayoutObj[UiResult]:
|
||||
|
@ -9,9 +9,12 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(msg: BinanceGetAddress, keychain: Keychain) -> BinanceAddress:
|
||||
async def get_address(
|
||||
msg: BinanceGetAddress, keychain: Keychain
|
||||
) -> BinanceAddress | None:
|
||||
from trezor.messages import BinanceAddress
|
||||
from trezor.ui.layouts import show_address
|
||||
from trezor.ui.layouts import show_address, show_continue_in_app
|
||||
from trezor.wire import context
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
@ -25,7 +28,11 @@ async def get_address(msg: BinanceGetAddress, keychain: Keychain) -> BinanceAddr
|
||||
node = keychain.derive(address_n)
|
||||
pubkey = node.public_key()
|
||||
address = address_from_public_key(pubkey, HRP)
|
||||
response = BinanceAddress(address=address)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERN, SLIP44_ID
|
||||
|
||||
await show_address(
|
||||
@ -34,5 +41,8 @@ async def get_address(msg: BinanceGetAddress, keychain: Keychain) -> BinanceAddr
|
||||
account=paths.get_account_name("BNB", address_n, PATTERN, SLIP44_ID),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return BinanceAddress(address=address)
|
||||
return response
|
||||
|
@ -11,19 +11,23 @@ if TYPE_CHECKING:
|
||||
@auto_keychain(__name__)
|
||||
async def get_public_key(
|
||||
msg: BinanceGetPublicKey, keychain: Keychain
|
||||
) -> BinancePublicKey:
|
||||
) -> BinancePublicKey | None:
|
||||
from ubinascii import hexlify
|
||||
|
||||
from trezor.messages import BinancePublicKey
|
||||
from trezor.ui.layouts import show_pubkey
|
||||
from trezor.ui.layouts import show_continue_in_app, show_pubkey
|
||||
from trezor.wire import context
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
await paths.validate_path(keychain, msg.address_n)
|
||||
node = keychain.derive(msg.address_n)
|
||||
pubkey = node.public_key()
|
||||
response = BinancePublicKey(public_key=pubkey)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERN, SLIP44_ID
|
||||
|
||||
path = paths.address_n_to_str(msg.address_n)
|
||||
@ -32,5 +36,8 @@ async def get_public_key(
|
||||
account=paths.get_account_name("BNB", msg.address_n, PATTERN, SLIP44_ID),
|
||||
path=path,
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__public_key_confirmed)
|
||||
return None
|
||||
|
||||
return BinancePublicKey(public_key=pubkey)
|
||||
return response
|
||||
|
@ -1,5 +1,6 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from trezor import TR
|
||||
from trezor.enums import MultisigPubkeysOrder
|
||||
|
||||
from apps.common import safety_checks
|
||||
@ -35,14 +36,18 @@ def _get_xpubs(
|
||||
|
||||
|
||||
@with_keychain
|
||||
async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Address:
|
||||
async def get_address(
|
||||
msg: GetAddress, keychain: Keychain, coin: CoinInfo
|
||||
) -> Address | None:
|
||||
from trezor.enums import InputScriptType
|
||||
from trezor.messages import Address
|
||||
from trezor.ui.layouts import (
|
||||
confirm_multisig_different_paths_warning,
|
||||
confirm_multisig_warning,
|
||||
show_address,
|
||||
show_continue_in_app,
|
||||
)
|
||||
from trezor.wire import context
|
||||
|
||||
from apps.common.address_mac import get_address_mac
|
||||
from apps.common.paths import address_n_to_str, validate_path
|
||||
@ -103,6 +108,8 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
|
||||
):
|
||||
mac = get_address_mac(address, coin.slip44, keychain)
|
||||
|
||||
response = Address(address=address, mac=mac)
|
||||
|
||||
if msg.show_display:
|
||||
path = address_n_to_str(address_n)
|
||||
if multisig:
|
||||
@ -156,4 +163,8 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
|
||||
return Address(address=address, mac=mac)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
else:
|
||||
return response
|
||||
|
@ -13,10 +13,11 @@ async def get_public_key(
|
||||
msg: GetPublicKey,
|
||||
auth_msg: MessageType | None = None,
|
||||
keychain: Keychain | None = None,
|
||||
) -> PublicKey:
|
||||
) -> PublicKey | None:
|
||||
from trezor import TR, wire
|
||||
from trezor.enums import InputScriptType
|
||||
from trezor.messages import HDNodeType, PublicKey, UnlockPath
|
||||
from trezor.wire import context
|
||||
|
||||
from apps.common import coininfo, paths
|
||||
from apps.common.keychain import FORBIDDEN_KEY_PATH, get_keychain
|
||||
@ -86,9 +87,19 @@ async def get_public_key(
|
||||
descriptor = _xpub_descriptor(
|
||||
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:
|
||||
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
|
||||
|
||||
@ -116,13 +127,11 @@ async def get_public_key(
|
||||
mismatch_title=TR.addr_mismatch__xpub_mismatch,
|
||||
br_name="show_xpub",
|
||||
)
|
||||
|
||||
return PublicKey(
|
||||
node=node_type,
|
||||
xpub=node_xpub,
|
||||
root_fingerprint=keychain.root_fingerprint(),
|
||||
descriptor=descriptor,
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__public_key_confirmed)
|
||||
return None
|
||||
else:
|
||||
return response
|
||||
|
||||
|
||||
def _xpub_descriptor(
|
||||
|
@ -9,9 +9,11 @@ if TYPE_CHECKING:
|
||||
@seed.with_keychain
|
||||
async def get_address(
|
||||
msg: CardanoGetAddress, keychain: seed.Keychain
|
||||
) -> CardanoAddress:
|
||||
) -> CardanoAddress | None:
|
||||
from trezor import log, wire
|
||||
from trezor.messages import CardanoAddress
|
||||
from trezor.ui.layouts import show_continue_in_app
|
||||
from trezor.wire import context
|
||||
|
||||
from . import addresses
|
||||
from .helpers.credential import Credential, should_show_credentials
|
||||
@ -32,7 +34,11 @@ async def get_address(
|
||||
log.exception(__name__, e)
|
||||
raise wire.ProcessError("Deriving address failed")
|
||||
|
||||
response = CardanoAddress(address=address)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
# _display_address
|
||||
if should_show_credentials(address_parameters):
|
||||
await show_credentials(
|
||||
@ -42,5 +48,8 @@ async def get_address(
|
||||
await show_cardano_address(
|
||||
address_parameters, address, msg.protocol_magic, chunkify=bool(msg.chunkify)
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return CardanoAddress(address=address)
|
||||
return response
|
||||
|
@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
@seed.with_keychain
|
||||
async def get_public_key(
|
||||
msg: CardanoGetPublicKey, keychain: seed.Keychain
|
||||
) -> CardanoPublicKey:
|
||||
) -> CardanoPublicKey | None:
|
||||
from trezor import log, wire
|
||||
from trezor.ui.layouts import show_pubkey
|
||||
|
||||
@ -37,10 +37,17 @@ async def get_public_key(
|
||||
raise wire.ProcessError("Deriving public key failed")
|
||||
|
||||
if msg.show_display:
|
||||
from trezor.ui.layouts import show_continue_in_app
|
||||
from trezor.wire import context
|
||||
|
||||
from apps.common.paths import address_n_to_str
|
||||
|
||||
path = address_n_to_str(address_n)
|
||||
await show_pubkey(key.xpub, TR.address__public_key, path=path)
|
||||
await context.write(key)
|
||||
await show_continue_in_app(TR.address__public_key_confirmed)
|
||||
return None
|
||||
|
||||
return key
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
||||
NodeType = TypeVar("NodeType", bound=NodeProtocol)
|
||||
|
||||
MsgIn = TypeVar("MsgIn", bound=MessageType)
|
||||
MsgOut = TypeVar("MsgOut", bound=MessageType)
|
||||
MsgOut = TypeVar("MsgOut", bound=MessageType | None)
|
||||
|
||||
Handler = Callable[[MsgIn], Awaitable[MsgOut]]
|
||||
HandlerWithKeychain = Callable[[MsgIn, "Keychain"], Awaitable[MsgOut]]
|
||||
|
@ -9,9 +9,13 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@auto_keychain(__name__)
|
||||
async def get_public_key(msg: EosGetPublicKey, keychain: Keychain) -> EosPublicKey:
|
||||
async def get_public_key(
|
||||
msg: EosGetPublicKey, keychain: Keychain
|
||||
) -> EosPublicKey | None:
|
||||
from trezor.crypto.curve import secp256k1
|
||||
from trezor.messages import EosPublicKey
|
||||
from trezor.ui.layouts import show_continue_in_app
|
||||
from trezor.wire import context
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
@ -24,11 +28,18 @@ async def get_public_key(msg: EosGetPublicKey, keychain: Keychain) -> EosPublicK
|
||||
|
||||
public_key = secp256k1.publickey(node.private_key(), True)
|
||||
wif = public_key_to_wif(public_key)
|
||||
response = EosPublicKey(wif_public_key=wif, raw_public_key=public_key)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERN, SLIP44_ID
|
||||
|
||||
path = paths.address_n_to_str(msg.address_n)
|
||||
account = paths.get_account_name("EOS", msg.address_n, PATTERN, SLIP44_ID)
|
||||
await require_get_public_key(wif, path, account)
|
||||
return EosPublicKey(wif_public_key=wif, raw_public_key=public_key)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__public_key_confirmed)
|
||||
return None
|
||||
|
||||
return response
|
||||
|
@ -15,9 +15,10 @@ async def get_address(
|
||||
msg: EthereumGetAddress,
|
||||
keychain: Keychain,
|
||||
defs: Definitions,
|
||||
) -> EthereumAddress:
|
||||
) -> EthereumAddress | None:
|
||||
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 context
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
@ -30,8 +31,11 @@ async def get_address(
|
||||
node = keychain.derive(address_n)
|
||||
|
||||
address = address_from_bytes(node.ethereum_pubkeyhash(), defs.network)
|
||||
response = EthereumAddress(address=address)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
slip44_id = address_n[1] # it depends on the network (ETH vs ETC...)
|
||||
await show_address(
|
||||
address,
|
||||
@ -41,5 +45,8 @@ async def get_address(
|
||||
),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return EthereumAddress(address=address)
|
||||
return response
|
||||
|
@ -4,19 +4,27 @@ if TYPE_CHECKING:
|
||||
from trezor.messages import EthereumGetPublicKey, EthereumPublicKey
|
||||
|
||||
|
||||
async def get_public_key(msg: EthereumGetPublicKey) -> EthereumPublicKey:
|
||||
async def get_public_key(msg: EthereumGetPublicKey) -> EthereumPublicKey | None:
|
||||
from ubinascii import hexlify
|
||||
|
||||
from trezor.messages import EthereumPublicKey, GetPublicKey
|
||||
from trezor.ui.layouts import show_pubkey
|
||||
from trezor.ui.layouts import show_continue_in_app, show_pubkey
|
||||
from trezor.wire import context
|
||||
|
||||
from apps.bitcoin import get_public_key as bitcoin_get_public_key
|
||||
|
||||
# we use the Bitcoin format for Ethereum xpubs
|
||||
btc_pubkey_msg = GetPublicKey(address_n=msg.address_n)
|
||||
resp = await bitcoin_get_public_key.get_public_key(btc_pubkey_msg)
|
||||
btc_pubkey_msg = GetPublicKey(address_n=msg.address_n, show_display=False)
|
||||
btc_resp = await bitcoin_get_public_key.get_public_key(btc_pubkey_msg)
|
||||
assert btc_resp is not None
|
||||
|
||||
response = EthereumPublicKey(node=btc_resp.node, xpub=btc_resp.xpub)
|
||||
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())
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__public_key_confirmed)
|
||||
return None
|
||||
|
||||
return response
|
||||
|
@ -171,6 +171,7 @@ async def _entropy_check(secret: bytes) -> bool:
|
||||
curve_name = req.ecdsa_curve_name or coininfo.by_name(req.coin_name).curve_name
|
||||
keychain = Keychain(seed, curve_name, [paths.AlwaysMatchingSchema])
|
||||
msg = await get_public_key(req, keychain=keychain)
|
||||
assert msg is not None
|
||||
|
||||
|
||||
async def _backup_bip39(mnemonic: str) -> None:
|
||||
|
@ -9,10 +9,13 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(msg: MoneroGetAddress, keychain: Keychain) -> MoneroAddress:
|
||||
async def get_address(
|
||||
msg: MoneroGetAddress, keychain: Keychain
|
||||
) -> MoneroAddress | None:
|
||||
from trezor import wire
|
||||
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 context
|
||||
|
||||
from apps.common import paths
|
||||
from apps.monero import misc
|
||||
@ -65,7 +68,11 @@ async def get_address(msg: MoneroGetAddress, keychain: Keychain) -> MoneroAddres
|
||||
crypto_helpers.encodepoint(pub_view),
|
||||
)
|
||||
|
||||
response = MoneroAddress(address=addr.encode())
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERN, SLIP44_ID
|
||||
|
||||
await show_address(
|
||||
@ -75,5 +82,8 @@ async def get_address(msg: MoneroGetAddress, keychain: Keychain) -> MoneroAddres
|
||||
account=paths.get_account_name("XMR", msg.address_n, PATTERN, SLIP44_ID),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return MoneroAddress(address=addr.encode())
|
||||
return response
|
||||
|
@ -11,9 +11,10 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@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) -> NEMAddress | None:
|
||||
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 context
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
@ -28,8 +29,11 @@ async def get_address(msg: NEMGetAddress, keychain: Keychain) -> NEMAddress:
|
||||
|
||||
node = keychain.derive(address_n)
|
||||
address = node.nem_address(network)
|
||||
response = NEMAddress(address=address)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERNS, SLIP44_ID
|
||||
|
||||
await show_address(
|
||||
@ -40,5 +44,8 @@ async def get_address(msg: NEMGetAddress, keychain: Keychain) -> NEMAddress:
|
||||
network=get_network_str(network),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return NEMAddress(address=address)
|
||||
return response
|
||||
|
@ -9,10 +9,13 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(msg: RippleGetAddress, keychain: Keychain) -> RippleAddress:
|
||||
async def get_address(
|
||||
msg: RippleGetAddress, keychain: Keychain
|
||||
) -> RippleAddress | None:
|
||||
# NOTE: local imports here saves 20 bytes
|
||||
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 context
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
@ -25,8 +28,11 @@ async def get_address(msg: RippleGetAddress, keychain: Keychain) -> RippleAddres
|
||||
node = keychain.derive(address_n)
|
||||
pubkey = node.public_key()
|
||||
address = address_from_public_key(pubkey)
|
||||
response = RippleAddress(address=address)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERN, SLIP44_ID
|
||||
|
||||
await show_address(
|
||||
@ -35,5 +41,8 @@ async def get_address(msg: RippleGetAddress, keychain: Keychain) -> RippleAddres
|
||||
account=paths.get_account_name("XRP", msg.address_n, PATTERN, SLIP44_ID),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return RippleAddress(address=address)
|
||||
return response
|
||||
|
@ -16,9 +16,10 @@ if TYPE_CHECKING:
|
||||
async def get_address(
|
||||
msg: SolanaGetAddress,
|
||||
keychain: Keychain,
|
||||
) -> SolanaAddress:
|
||||
) -> SolanaAddress | None:
|
||||
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 context
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
@ -26,12 +27,18 @@ async def get_address(
|
||||
|
||||
public_key = derive_public_key(keychain, msg.address_n)
|
||||
address = base58.encode(public_key)
|
||||
response = SolanaAddress(address=address)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
await show_address(
|
||||
address,
|
||||
path=paths.address_n_to_str(msg.address_n),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return SolanaAddress(address=address)
|
||||
return response
|
||||
|
@ -16,19 +16,26 @@ if TYPE_CHECKING:
|
||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||
async def get_public_key(
|
||||
msg: SolanaGetPublicKey, keychain: Keychain
|
||||
) -> SolanaPublicKey:
|
||||
) -> SolanaPublicKey | None:
|
||||
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 context
|
||||
|
||||
public_key = derive_public_key(keychain, msg.address_n)
|
||||
response = SolanaPublicKey(public_key=public_key)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from apps.common.paths import address_n_to_str
|
||||
|
||||
path = address_n_to_str(msg.address_n)
|
||||
await show_pubkey(base58.encode(public_key), path=path)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__public_key_confirmed)
|
||||
return None
|
||||
|
||||
return SolanaPublicKey(public_key=public_key)
|
||||
return response
|
||||
|
||||
|
||||
def derive_public_key(keychain: Keychain, address_n: list[int]) -> bytes:
|
||||
|
@ -9,9 +9,12 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@auto_keychain(__name__)
|
||||
async def get_address(msg: StellarGetAddress, keychain: Keychain) -> StellarAddress:
|
||||
async def get_address(
|
||||
msg: StellarGetAddress, keychain: Keychain
|
||||
) -> StellarAddress | None:
|
||||
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 context
|
||||
|
||||
from apps.common import paths, seed
|
||||
|
||||
@ -24,8 +27,11 @@ async def get_address(msg: StellarGetAddress, keychain: Keychain) -> StellarAddr
|
||||
node = keychain.derive(address_n)
|
||||
pubkey = seed.remove_ed25519_prefix(node.public_key())
|
||||
address = helpers.address_from_public_key(pubkey)
|
||||
response = StellarAddress(address=address)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERN, SLIP44_ID
|
||||
|
||||
await show_address(
|
||||
@ -35,5 +41,8 @@ async def get_address(msg: StellarGetAddress, keychain: Keychain) -> StellarAddr
|
||||
account=paths.get_account_name("XLM", msg.address_n, PATTERN, SLIP44_ID),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return StellarAddress(address=address)
|
||||
return response
|
||||
|
@ -11,10 +11,11 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@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) -> TezosAddress | None:
|
||||
from trezor.crypto import hashlib
|
||||
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 context
|
||||
|
||||
from apps.common import paths, seed
|
||||
|
||||
@ -29,8 +30,11 @@ async def get_address(msg: TezosGetAddress, keychain: Keychain) -> TezosAddress:
|
||||
pk = seed.remove_ed25519_prefix(node.public_key())
|
||||
pkh = hashlib.blake2b(pk, outlen=helpers.PUBLIC_KEY_HASH_SIZE).digest()
|
||||
address = helpers.base58_encode_check(pkh, helpers.TEZOS_ED25519_ADDRESS_PREFIX)
|
||||
response = TezosAddress(address=address)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERNS, SLIP44_ID
|
||||
|
||||
await show_address(
|
||||
@ -39,5 +43,8 @@ async def get_address(msg: TezosGetAddress, keychain: Keychain) -> TezosAddress:
|
||||
account=paths.get_account_name("XTZ", address_n, PATTERNS, SLIP44_ID),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__confirmed)
|
||||
return None
|
||||
|
||||
return TezosAddress(address=address)
|
||||
return response
|
||||
|
@ -11,9 +11,12 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@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
|
||||
) -> TezosPublicKey | None:
|
||||
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 context
|
||||
|
||||
from apps.common import paths, seed
|
||||
|
||||
@ -24,12 +27,18 @@ async def get_public_key(msg: TezosGetPublicKey, keychain: Keychain) -> TezosPub
|
||||
node = keychain.derive(msg.address_n)
|
||||
pk = seed.remove_ed25519_prefix(node.public_key())
|
||||
pk_prefixed = helpers.base58_encode_check(pk, helpers.TEZOS_PUBLICKEY_PREFIX)
|
||||
response = TezosPublicKey(public_key=pk_prefixed)
|
||||
|
||||
if msg.show_display:
|
||||
from trezor import TR
|
||||
|
||||
from . import PATTERNS, SLIP44_ID
|
||||
|
||||
account = paths.get_account_name("XTZ", msg.address_n, PATTERNS, SLIP44_ID)
|
||||
path = paths.address_n_to_str(msg.address_n)
|
||||
await show_pubkey(pk_prefixed, account=account, path=path)
|
||||
await context.write(response)
|
||||
await show_continue_in_app(TR.address__public_key_confirmed)
|
||||
return None
|
||||
|
||||
return TezosPublicKey(public_key=pk_prefixed)
|
||||
return response
|
||||
|
@ -399,6 +399,10 @@ def show_success(
|
||||
)
|
||||
|
||||
|
||||
async def show_continue_in_app(content: str) -> None:
|
||||
return
|
||||
|
||||
|
||||
async def confirm_output(
|
||||
address: str,
|
||||
amount: str,
|
||||
|
@ -463,6 +463,10 @@ def show_success(
|
||||
)
|
||||
|
||||
|
||||
async def show_continue_in_app(content: str) -> None:
|
||||
return
|
||||
|
||||
|
||||
async def confirm_output(
|
||||
address: str,
|
||||
amount: str,
|
||||
|
@ -235,12 +235,6 @@ async def show_address(
|
||||
)
|
||||
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(
|
||||
trezorui_api.flow_get_address(
|
||||
address=address,
|
||||
@ -253,7 +247,6 @@ async def show_address(
|
||||
account=account,
|
||||
path=path,
|
||||
xpubs=[(xpub_title(i), xpub) for i, xpub in enumerate(xpubs)],
|
||||
title_success=title_success,
|
||||
br_name=br_name,
|
||||
br_code=br_code,
|
||||
),
|
||||
@ -349,22 +342,33 @@ def show_danger(
|
||||
|
||||
|
||||
def show_success(
|
||||
br_name: str,
|
||||
br_name: str | None,
|
||||
content: str,
|
||||
subheader: str | None = None,
|
||||
button: str | None = None,
|
||||
time_ms: int = 0,
|
||||
) -> Awaitable[None]:
|
||||
return raise_if_not_confirmed(
|
||||
trezorui_api.show_success(
|
||||
title=content,
|
||||
button="",
|
||||
description=subheader if subheader else "",
|
||||
button=button or "",
|
||||
description=subheader or "",
|
||||
time_ms=time_ms,
|
||||
),
|
||||
br_name,
|
||||
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(
|
||||
address: str,
|
||||
amount: str | None = None,
|
||||
|
@ -79,6 +79,16 @@ async def call_any(
|
||||
return await CURRENT_CONTEXT.read(expected_wire_types)
|
||||
|
||||
|
||||
async def write(msg: protobuf.MessageType) -> None:
|
||||
"""Send a message to the host.
|
||||
|
||||
Raises if there is no context for this workflow."""
|
||||
if CURRENT_CONTEXT is None:
|
||||
raise RuntimeError("No wire context")
|
||||
|
||||
await CURRENT_CONTEXT.write(msg)
|
||||
|
||||
|
||||
async def maybe_call(
|
||||
msg: protobuf.MessageType, expected_type: type[LoadedMessageType]
|
||||
) -> None:
|
||||
|
Loading…
Reference in New Issue
Block a user